Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无符号整数实现——将C#移植到Java_C#_Java_Cryptography - Fatal编程技术网

无符号整数实现——将C#移植到Java

无符号整数实现——将C#移植到Java,c#,java,cryptography,C#,Java,Cryptography,我正在将数千行加密C#函数移植到一个Java项目中。C代码广泛使用无符号值和位运算 我知道支持无符号值所需的Java变通方法。然而,如果有无符号32位整数和64位整数的实现,我可以将它们放入代码中,这将更加方便。请链接到这样一个库 快速谷歌查询揭示了商业应用程序的几个组成部分: 这是一种语言特性,而不是库特性,因此除非您更改语言本身,否则无法扩展Java以支持此功能,在这种情况下,您需要制作自己的编译器 但是,如果您需要无符号右移,Java支持>运算符,它的工作原理与无符号类型的>运算符类

我正在将数千行加密C#函数移植到一个Java项目中。C代码广泛使用无符号值和位运算

我知道支持无符号值所需的Java变通方法。然而,如果有无符号32位整数和64位整数的实现,我可以将它们放入代码中,这将更加方便。请链接到这样一个库

快速谷歌查询揭示了商业应用程序的几个组成部分:


    • 这是一种语言特性,而不是库特性,因此除非您更改语言本身,否则无法扩展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)){…}

    知道了这一点,签名的Java类型对于加密代码来说并不是一个大麻烦。我已经在Java中实现了许多加密原语,并且只要您理解您正在编写的内容,签名的类型就不是一个问题。例如,看看:这是一个开源库,它实现了许多加密哈希函数,包括Java代码非常无缝地使用了Java的签名类型(
    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));
    }