我在C代码中做了两个SHA1,一个用于字符串,另一个用于整数,得到不同的结果。
SHA_init(&ctx);
SHA_update(&ctx, "1234", 4);
sha = SHA_final(&ctx);
unsigned n = 1234;
SHA_init(&ctx);
SHA_update(&ctx, &n, sizeof(n));
sha = SHA_final(&ctx);
string result: 7110eda4d09e62aa5e4a390b0a572acd2c220
integer result: c7f07b846cc46631c2079cdd7179afdd783d643
在python中,很容易得到字符串SHA1
sha1 = hashlib.sha1()
sha1.update('1234')
sha1.hexdigest()
'7110eda4d09e062aa5e4a390b0a572ac0d2c0220'
我们可以看到字符串结果与C代码相同。但是如何在python中获取整数SHA1?因为python sha1不支持整数。
我尝试了以下代码,但它无法获得与C代码相同的结果。
aint = unpack('>4B', pack('>I', 1234))
sha1 = hashlib.sha1()
sha1.update(bytearray(aint))
sha1.hexdigest()
'ac9928e78cf6ea117451ecd6654fea2adae73e21'
如何在python中执行整数SHA1?
答案 0 :(得分:3)
digest = sha1.hexdigest()
digest_int = int(digest,16)
答案 1 :(得分:2)
我无法在C中重现您的结果,您使用的是什么SHA库? OpenSSL推荐使用SHA1_*
函数,但表示包含SHA_*
是为了兼容性。这两个给我不同的结果,所以如果你要比较Pythons SHA1,你应该使用SHA1_*
#include <openssl/sha.h>
#include <stdio.h>
int main(void) {
unsigned n = 1234;
unsigned char md[50];
SHA_CTX c;
for (int i=0; i<sizeof(n); i++) {
printf("%02x ", ((unsigned char*)&n)[i]);
}
printf("\n");
SHA1_Init(&c);
SHA1_Update(&c, &n, 4);
SHA1_Final(md, &c);
for (int i=0; i<20; i++) {
printf("%02x", md[i]);
}
printf("\n");
return 0;
}
给出:
d2 04 00 00
7b08e025e311c3dfcf5179b67c0fdc08e73de261
这表明你在python实现中以错误的顺序打包字节。它应该是:
>>> import hashlib
>>> hashlib.sha1(b'\xd2\x04\x00\x00').hexdigest()
'7b08e025e311c3dfcf5179b67c0fdc08e73de261'
>>> hashlib.sha1(bytearray(unpack('>4B', pack('I', 1234)))).hexdigest()
'7b08e025e311c3dfcf5179b67c0fdc08e73de261'
(注意>
前面的I
)与上面的shasum匹配。
作为参考,如果我使用SHA_*
函数
int main(void) {
unsigned n = 1234;
unsigned char md[50];
SHA_CTX c;
SHA_Init(&c);
SHA_Update(&c, &n, 4);
SHA_Final(md, &c);
for (int i=0; i<20; i++) {
printf("%02x", md[i]);
}
printf("\n");
return 0;
}
3e491ac1d065d6d666e5e216e0cddf60fcb5be86
这似乎与Python中的SHA(“SHA-0”)值一致:
>>> hashlib.new('sha', b'\xd2\x04\x00\x00').hexdigest()
'3e491ac1d065d6d666e5e216e0cddf60fcb5be86'
答案 2 :(得分:1)
可能是您的代码转换为十六进制以进行打印。请注意你的哈希值是多少都不是40个字符?尝试使用下面的to_hex()方法。
python ==> '7110eda4d09e062aa5e4a390b0a572ac0d2c0220'
string result: 7110eda4d09e62aa5e4a390b0a572acd2c220
integer result: c7f07b846cc46631c2079cdd7179afdd783d643
我也无法重现您的C结果。这是一个OSX版本:
#include <stdio.h>
#include <CommonCrypto/CommonDigest.h>
char *to_hex(unsigned char *buffer, size_t len) {
static char out[100];
char *p = out;
while (len--)
p += sprintf(p, "%02x", *buffer++);
*p = 0;
return out;
}
int main() {
unsigned char buffer[21] = { 0 };
printf("SHA1(\"1234\") = %s\n", to_hex(CC_SHA1("1234", 4, buffer), 20));
unsigned n = 1234;
printf("1234 LE = %s\n", to_hex(&n, 4));
printf("SHA1(1234 LE) = %s\n", to_hex(CC_SHA1(&n, 4, buffer), 20));
n = htonl(n);
printf("1234 BE = %s\n", to_hex(&n, 4));
printf("SHA1(1234 BE) = %s\n", to_hex(CC_SHA1(&n, 4, buffer), 20));
return 0;
}
这里是Android版
#include <stdio.h>
#include "mincrypt/sha.h"
char *to_hex(unsigned char *buffer, size_t len) {
static char out[100];
char *p = out;
while (len--)
p += sprintf(p, "%02x", *buffer++);
*p = 0;
return out;
}
int main() {
unsigned char buffer[21] = { 0 };
printf("SHA1(\"1234\") = %s\n", to_hex(SHA1_hash("1234", 4, buffer), 20));
unsigned n = 1234;
printf("1234 LE = %s\n", to_hex(&n, 4));
printf("SHA1(1234 LE) = %s\n", to_hex(SHA1_hash(&n, 4, buffer), 20));
n = htonl(n);
printf("1234 BE = %s\n", to_hex(&n, 4));
printf("SHA1(1234 BE) = %s\n", to_hex(SHA1_hash(&n, 4, buffer), 20));
return 0;
}
该文件位于system/core/libmincrypt
并使用cc -I../include -o sha_test sha_test.c sha.c
两个程序产生相同的结果
SHA1("1234") = 7110eda4d09e062aa5e4a390b0a572ac0d2c0220
1234 LE = d2040000
SHA1(1234 LE) = 7b08e025e311c3dfcf5179b67c0fdc08e73de261
1234 BE = 000004d2
SHA1(1234 BE) = ac9928e78cf6ea117451ecd6654fea2adae73e21