我有将纯Java Curve25519函数转换为Python等效的问题,具体问题与将哈希字符串转换为字节等效的摘要函数有关,java实现:
数据示例:
sP ="这是用于测试目的的秘密密码短语样本"
/**
* Calculate the SHA-256 hash of a string
*
* @param input Data to be hashed
* @return The hash digest
*/
public static byte[] singleDigest(String input) {
byte[] bytes;
try {
bytes = singleDigest(input.getBytes("UTF-8"));
System.out.println("bytes"+bytes);
System.out.println("before singleDigest"+input);
} catch (UnsupportedEncodingException exc) {
bytes = null;
}
return bytes;
}
/**
* Calculate the SHA-256 hash of a byte array
*
* @param input Data to be hashed
* @return The hash digest
*/
public static byte[] singleDigest(byte[] input) {
byte[] bytes;
synchronized (digest) {
digest.reset();
bytes = digest.digest(input);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
System.out.println(bytes[i]);
sb.append(String.format("%02x", bytes[i] & 0xFF));
}
System.out.println(sb.toString());
}
return bytes;
}
生成此字节输出:
byteOutput:82,-57,124,58,-105,76,123,3,119,-21,121,71,-54,73,-75,54,31,-33,-49, -68,-16,-19,125,-61,-116,-82,96,50,-35,-119,-28,25
有正数和负数,在python端,我使用此函数将散列字符串转换为byte:
secret = sha256(sP.encode('utf-8')).hexdigest()
sct = ParseHexString(secret).getData()
class ParseHexString(object):
def __init__(self, hex):
"""
"""
if not isinstance(hex, str):
return None
else:
self.hex = hex
self.listOfByte = None
self.run()
def run(self):
if len(self.hex)&0x01 == 1:
return None
lbytes = []
for i in range(0, len(self.hex), 2):
op1, op2 = self.hex[i:i + 2]
oop1 = ord(op1)
oop2 = ord(op2)
char1 = oop1 - 0x57 if oop1 > 0x60 else oop1 - 0x30
char2 = oop2 - 0x57 if oop2 > 0x60 else oop2 - 0x30
if (char1 < 0 or char2 < 0 or char1 > 15 or char2 > 15):
print("Invalid hex number ",op1,op2)
lbytes.append(((char1 << 4) + char2))
self.listOfByte = lbytes
def getData(self):
return self.listOfByte
由于bytearray(0 - 256)的内部表示,以及某些散列字符串的输出,我在这里使用了列表而不是可变的bytearray 是不同的,只是正整数:
82,199,124,58,151,76,123,3,119,235,121,71,202,73,181,54,31,217,207,188,240,237,125,196 ,140,174,96,50,221,137,228,25
我注意到(256 - JavaByteOutput [x] == PythonByteOtput [x])当JavaByteOutput是负数时,问题是,我如何修改我的ParseHexString类以获得等效的正/负输出,我想要纯粹的python代码,没有库。
感谢您的回答。 问候 亚历
答案 0 :(得分:1)
这里的重点:Java只知道签名类型。
这意味着:虽然Java字节也是大约8位,但范围是-128到127.无符号字节从0到255.
这就是全部。唯一真正重要的是你对价值观的处理方式保持一致。有关此主题的进一步想法,请参阅here。
答案 1 :(得分:1)
在Python中,a % b
始终返回一个值与b
相同的值,介于0(包括)和b
之间(不包括)。在这种情况下,b
为256。
所以要将值移到范围[-128,128],每个值加128,取模数基数256然后减去128:
x = [82, 199, 124, 58, 151, 76, 123, 3, 119, 235, 121, 71, 202, 73, 181, 54, 31, 217, 207, 188, 240, 237, 125, 196, 140, 174, 96, 50, 221, 137, 228, 25]
y = [(xi + 128) % 256 - 128 for xi in x]
# [82, -57, 124, 58, -105, 76, 123, 3, 119, -21, 121, 71, -54, 73, -75, 54, 31, -39, -49, -68, -16, -19, 125, -60, -116, -82, 96, 50, -35, -119, -28, 25]
因此,在ParseHexString.run
中定义:
self.listOfByte = [(xi + 128) % 256 - 128 for xi in lbytes]
如果NumPy是一个选项,你可以简单地view
无符号的1字节整数作为带符号的1字节整数:
import numpy as np
x = np.array([82, 199, 124, 58, 151, 76, 123, 3, 119, 235, 121, 71, 202, 73, 181, 54, 31, 217, 207, 188, 240, 237, 125, 196, 140, 174, 96, 50, 221, 137, 228, 25], dtype='uint8')
x.view('i1')
# array([ 82, -57, 124, 58, -105, 76, 123, 3, 119, -21, 121,
# 71, -54, 73, -75, 54, 31, -39, -49, -68, -16, -19,
# 125, -60, -116, -82, 96, 50, -35, -119, -28, 25], dtype=int8)