我试图在Python中复制此哈希代码,但这两种语言处理字节的方式不同,并生成非常不同的输出
有人能带我到这里吗
Java代码(原始代码)
public static String hash(String filePath, String salt) {
String finalHash = null;
Path path = Paths.get(filePath);
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] data = Files.readAllBytes(path);
byte[] dataDigest = md.digest(data);
byte[] hashDigest = md.digest(salt.getBytes("ISO-8859-1"));
byte[] xorBytes = new byte[dataDigest.length];
for (int i = 0; i < dataDigest.length && i < hashDigest.length; i++) {
xorBytes[i] = (byte) (dataDigest[i] << 1 ^ hashDigest[i] >> 1);
}
finalHash = (new HexBinaryAdapter()).marshal(xorBytes);
} catch (IOException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
return finalHash;
}
Python代码(由我翻译)
def generate_hash(file_path: str, salt: bytes) -> str:
with open(file_path, 'rb') as f:
data = f.read()
hashed_file = sha1(data).digest()
hashed_salt = sha1(salt).digest()
xor_bytes = []
for i in range(len(hashed_file)):
xor_bytes.append((hashed_file[i] << 1 ^ hashed_salt[i] >> 1))
return ''.join(map(chr, xor_bytes)) # This is probably not equivalent of HexBinaryAdapter
有以下问题:
在Python代码中错误地实现了shift操作:
在Python代码中,生成的散列存储在类似字节的对象中,作为
0
和255
{a1}之间的无符号整数值列表,例如0xc8 = 11001000 = 200
。在Java中,整数存储为有符号值,其中二者的补码用于表示负数[2][3]。如果值0x8c
存储在byte
变量中,则该值将被解释为-56
>>
-运算符在有符号值和无符号值的二进制级别上产生不同的结果,因为它是一个算术移位运算符,保留符号[4]{a5}[6]。例如:另一方面,
<<
-运算符不会导致上述问题,但会导致无法用字节表示的值。例如:出于这些原因,在Python代码中
必须由
在哪里
确定两个补码表示的负值(或更复杂的位运算符,请参见[7])
将按位和(
&
)与0xFF
一起使用可确保Python代码中只考虑相关字节,类似于Java代码[5]有几种方法可以将list/bytes-like对象转换为十六进制字符串(如Java代码),例如使用[8][9]
或与[8][10](作为二进制字符串)一起使用
在Python代码中,必须考虑salt的编码。由于salt已作为二进制字符串传递(在Java代码中它作为字符串传递),因此必须在调用函数之前执行编码:
为了与Java代码保持函数一致性,salt必须作为字符串传递,编码必须在函数中执行
相关问题 更多 >
编程相关推荐