Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.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
迭代哈希在Python和Java中返回不同的值_Java_Python_Sha256 - Fatal编程技术网

迭代哈希在Python和Java中返回不同的值

迭代哈希在Python和Java中返回不同的值,java,python,sha256,Java,Python,Sha256,我正在尝试将python(2.7)脚本移植到Java。它多次迭代sha256哈希,但结果不同。我注意到他们第一次返回相同的结果,但从那以后就不同了 以下是Python实现: import hashlib def to_hex(s): print " ".join(hex(ord(i)) for i in s) d = hashlib.sha256() print "Entry:" r = chr(1) to_hex(r) for i in range(2): print "Loo

我正在尝试将python(2.7)脚本移植到Java。它多次迭代sha256哈希,但结果不同。我注意到他们第一次返回相同的结果,但从那以后就不同了

以下是Python实现:

import hashlib

def to_hex(s):
  print " ".join(hex(ord(i)) for i in s)

d = hashlib.sha256()

print "Entry:"
r = chr(1)
to_hex(r)

for i in range(2):
  print "Loop", i
  d.update(r)
  r = d.digest()
  to_hex(r)
在Java中:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class LoopTest {

  public static void main(String[] args) {
    MessageDigest d;
    try {
      d = MessageDigest.getInstance("SHA-256");
    } catch (NoSuchAlgorithmException e) {
      System.out.println("NoSuchAlgorithmException");
      return;
    }

    System.out.println("Entry:");
    byte[] r = new byte[] {1};
    System.out.println(toHex(r));

    for(int i = 0; i < 2; i++) {
      System.out.printf("Loop %d\n", i);
      d.update(r);
      r = d.digest();
      System.out.println(toHex(r));
    }
  }

  private static String toHex(byte[] bytes) {
    StringBuilder sb = new StringBuilder(bytes.length);
    for (byte b: bytes) {
       sb.append(String.format("0x%02X ", b));
    }
    return sb.toString();
  }
}
对于java:

$ java LoopTest
Entry:
0x01
Loop 0
0x4B 0xF5 0x12 0x2F 0x34 0x45 0x54 0xC5 0x3B 0xDE 0x2E 0xBB 0x8C 0xD2 0xB7 0xE3 0xD1 0x60 0x0A 0xD6 0x31 0xC3 0x85 0xA5 0xD7 0xCC 0xE2 0x3C 0x77 0x85 0x45 0x9A
Loop 1
0x9C 0x12 0xCF 0xDC 0x04 0xC7 0x45 0x84 0xD7 0x87 0xAC 0x3D 0x23 0x77 0x21 0x32 0xC1 0x85 0x24 0xBC 0x7A 0xB2 0x8D 0xEC 0x42 0x19 0xB8 0xFC 0x5B 0x42 0x5F 0x70
造成这种差异的原因是什么

编辑:

谢谢你的回答@dcsohl和@Alik我现在明白原因了。因为我要将Python脚本移植到Java,所以我必须保持Python脚本的原样,所以我修改了Java程序,如下所示:

byte[] r2 = new byte[]{};
for(int i = 0; i < 2; i++) {
  System.out.printf("Loop %d\n", i);
  d.update(r);
  r2 = d.digest();
  System.out.println(toHex(r2));
  byte[] c = new byte[r.length + r2.length];
  System.arraycopy(r, 0, c, 0, r.length);
  System.arraycopy(r2, 0, c, r.length, r2.length);
  r = c;
}
byte[]r2=新字节[]{};
对于(int i=0;i<2;i++){
System.out.printf(“循环%d\n”,i);
d、 更新(r);
r2=d.摘要();
系统输出println(toHex(r2));
字节[]c=新字节[r.length+r2.length];
数组复制(r,0,c,0,r.length);
系统阵列复制(r2,0,c,r长度,r2长度);
r=c;
}

这两种语言的运行方式不同

update()
的python文档说

使用字符串arg更新哈希对象。重复调用相当于连接所有参数的单个调用:
m.update(a);m、 update(b)
相当于
m.update(a+b)

我使用shell
sha256sum
命令对此进行了测试

echo -n '\0x01\0x4b\0xf5\0x12\0x2f\0x34\0x45\0x54\0xc5\0x3b\0xde\0x2e\0xbb\0x8c\0xd2\0xb7\0xe3\0xd1\0x60\0xa\0xd6\0x31\0xc3\0x85\0xa5\0xd7\0xcc\0xe2\0x3c\0x77\0x85\0x45\0x9a' | sha256sum
981fc8d471a8b01932e384ac1cd0a062c4db2c0e1358619a83d167f5e84e6a17 *-
您从\0x01开始,这是第一个字节,其余字节是0x01的散列。结果哈希与Python输出匹配

现在看看这个-我省略了初始\0x01并得到了哈希值-它与Java输出匹配

> echo -n '\0x4b\0xf5\0x12\0x2f\0x34\0x45\0x54\0xc5\0x3b\0xde\0x2e\0xbb\0x8c\0xd2\0xb7\0xe3\0xd1\0x60\0xa\0xd6\0x31\0xc3\0x85\0xa5\0xd7\0xcc\0xe2\0x3c\0x77\0x85\0x45\0x9a' | sha256sum
9c12cfdc04c74584d787ac3d23772132c18524bc7ab28dec4219b8fc5b425f70 *-
但是为什么呢?不应该包括首字母\0x01吗?除了
digest()
的javadoc说:

通过执行最后的操作(如填充)完成哈希计算。进行此调用后,将重置摘要

因此,在java中调用
digest()
时,您的初始\0x01将被删除,您只需在没有初始\0x01项的情况下消化旧的摘要。

在java中返回消息摘要并在最后重置摘要

在Python中,d.digest不会重置摘要。因此,重复调用
d.update
实际上与先前调用中传递的内容连接在一起

您只需将
d=hashlib.sha256()
放入循环中即可

import hashlib

def to_hex(s):
  print " ".join(hex(ord(i)) for i in s)



print "Entry:"
r = chr(1)
to_hex(r)

for i in range(2):
  print "Loop", i
  d = hashlib.sha256()
  d.update(r)
  r = d.digest()
  to_hex(r)
以获得与java程序相同的结果

Entry:
0x1
Loop 0
0x4b 0xf5 0x12 0x2f 0x34 0x45 0x54 0xc5 0x3b 0xde 0x2e 0xbb 0x8c 0xd2 0xb7 0xe3 0xd1 0x60 0xa 0xd6 0x31 0xc3 0x85 0xa5 0xd7 0xcc 0xe2 0x3c 0x77 0x85 0x45 0x9a
Loop 1
0x9c 0x12 0xcf 0xdc 0x4 0xc7 0x45 0x84 0xd7 0x87 0xac 0x3d 0x23 0x77 0x21 0x32 0xc1 0x85 0x24 0xbc 0x7a 0xb2 0x8d 0xec 0x42 0x19 0xb8 0xfc 0x5b 0x42 0x5f 0x70
Entry:
0x1
Loop 0
0x4b 0xf5 0x12 0x2f 0x34 0x45 0x54 0xc5 0x3b 0xde 0x2e 0xbb 0x8c 0xd2 0xb7 0xe3 0xd1 0x60 0xa 0xd6 0x31 0xc3 0x85 0xa5 0xd7 0xcc 0xe2 0x3c 0x77 0x85 0x45 0x9a
Loop 1
0x9c 0x12 0xcf 0xdc 0x4 0xc7 0x45 0x84 0xd7 0x87 0xac 0x3d 0x23 0x77 0x21 0x32 0xc1 0x85 0x24 0xbc 0x7a 0xb2 0x8d 0xec 0x42 0x19 0xb8 0xfc 0x5b 0x42 0x5f 0x70