无符号整数实现——将C#移植到Java
我正在将数千行加密C#函数移植到一个Java项目中。C代码广泛使用无符号值和位运算 我知道支持无符号值所需的Java变通方法。然而,如果有无符号32位整数和64位整数的实现,我可以将它们放入代码中,这将更加方便。请链接到这样一个库 快速谷歌查询揭示了商业应用程序的几个组成部分:无符号整数实现——将C#移植到Java,c#,java,cryptography,C#,Java,Cryptography,我正在将数千行加密C#函数移植到一个Java项目中。C代码广泛使用无符号值和位运算 我知道支持无符号值所需的Java变通方法。然而,如果有无符号32位整数和64位整数的实现,我可以将它们放入代码中,这将更加方便。请链接到这样一个库 快速谷歌查询揭示了商业应用程序的几个组成部分: 这是一种语言特性,而不是库特性,因此除非您更改语言本身,否则无法扩展Java以支持此功能,在这种情况下,您需要制作自己的编译器 但是,如果您需要无符号右移,Java支持>运算符,它的工作原理与无符号类型的>运算符类
- 这是一种语言特性,而不是库特性,因此除非您更改语言本身,否则无法扩展Java以支持此功能,在这种情况下,您需要制作自己的编译器
但是,如果您需要无符号右移,Java支持
>
运算符,它的工作原理与无符号类型的>
运算符类似
但是,您可以创建自己的方法来对有符号类型执行算术,就像它们是无符号的一样;这应该有效,例如:
static int multiplyUnsigned(int a, int b)
{
final bool highBitA = a < 0, highBitB = b < 0;
final long a2 = a & ~(1 << 31), b2 = b & ~(1 << 31);
final long result = (highBitA ? a2 | (1 << 31) : a2)
* (highBitB ? b2 | (1 << 31) : b2);
return (int)result;
}
静态整数多重签名(整数a、整数b)
{
最终布尔高位a=a<0,高位b=b<0;
最终长a2=a&~(1当使用二的补码表示法时,有符号整数和无符号整数的运算基本相同,Java就是这么做的。这意味着,如果您有两个32位的字a
和b
,并且要计算它们的和a+b
,那么无论你认为单词是有符号的或无符号的。这将对加法、减法和乘法适用。
必须了解签名的操作包括:
- 右移:有符号右移复制符号位,而无符号右移总是插入零。Java为无符号右移提供“
>
”运算符
- 除法:无符号除法不同于有符号除法。使用32位整数时,可以将值转换为64位
long
类型(“x&0xffffffffffl
”执行“无符号转换”技巧)
a
与b
作为两个32位无符号字进行比较,则有两种标准习惯用法:
if((a+Integer.MIN_值)<(b+Integer.MIN_值)){…}
if((a&0xFFFFFFFFL)<(b&0xFFFFFFFFL)){…}
int
,long
…),而且工作简单
Java没有运算符重载,因此获取无符号类型的纯Java“解决方案”将涉及自定义类(例如链接到的UInt64
类),这将意味着巨大的性能损失。您确实不想这样做
从理论上讲,我们可以定义一种具有无符号类型的类Java语言,并实现一个为JVM生成字节码的编译器(在内部使用我上面详细介绍的移位、除法和比较技巧)。我不知道有任何可用的工具可以做到这一点;而且,正如我前面所说,Java的签名类型对于加密代码来说很好(换句话说,如果您在使用此类签名类型时遇到问题,那么我敢说您对安全实现加密代码了解不够,您应该避免这样做;相反,请使用现有的开源库).谢谢您的回复,但我非常了解
运算符。我真的希望能够在Java中实现和无符号整数对象,包括必要的运算符重载。商业项目的文档(如)给了我希望。我认为乘法函数返回的结果与“当设置高位时,将显示正确的结果。@Karl:Java不支持运算符重载。出于加密目的,对象将非常慢;您需要Java中不存在的原始无符号类型。@Ben:是的,您是对的;我编辑了它,这个应该可以。@Mehrdad:如果您有一个更宽的整数类型,您可以简单地执行<代码>长掩码=(1L顺便说一句,我忘了问:在这些库中,你到底在寻找什么样的功能,而这些功能是用类似于我下面所写的东西做不到的?@Mehrdad我对Java的误解也可能扭曲了我的假设。我可能会接受Thomas Pornin关于整合通用技术的回答,尽管它们是这正是我试图避免的。老实说,位运算中没有多少“专业知识”;你真的可以自己做。但是,以什么方式聪明呢?如果你指的是速度,那是一件事,但除此之外,我认为问题在于正确性,而不是聪明。(而且,如果你觉得托马斯的回答更有用,那么你当然会接受他的回答!:)
static int multiplyUnsigned(int a, int b)
{
final long mask = (1L << 32) - 1;
return (int)((a & mask) * (b & mask));
}