2015-07-02 15 views
6

Tôi đã làm hai SHA1 trong mã C, một là cho một chuỗi, và một là cho một số nguyên, và có được kết quả khác nhau.Python SHA1 Integer

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 

Trong python, nó rất dễ dàng để có được những chuỗi SHA1

sha1 = hashlib.sha1() 
sha1.update('1234') 
sha1.hexdigest() 

'7110eda4d09e062aa5e4a390b0a572ac0d2c0220' 

Chúng ta có thể xem kết quả chuỗi là giống như mã C. Nhưng làm thế nào để có được số nguyên SHA1 trong python? vì python sha1 không hỗ trợ số nguyên.

Tôi đã thử mã sau nhưng không thể nhận được kết quả tương tự như mã C.

aint = unpack('>4B', pack('>I', 1234)) 
sha1 = hashlib.sha1() 
sha1.update(bytearray(aint)) 
sha1.hexdigest() 

'ac9928e78cf6ea117451ecd6654fea2adae73e21'

Làm thế nào để làm SHA1 số nguyên trong python?

+0

Gợi ý: 'bản đồ (ord," 1234 ") == [49, 50, 51, 52]! = [210, 4] == [1234 & 0xff, 1234 >> 8]' – kay

+0

Làm thế nào về 'sha1.cập nhật (str (1234)) '? – ycsun

+0

Tất nhiên, 'sha1.update (str (1234))' giống như 'sha1.update ('1234')' –

Trả lời

2

Tôi không thể sao chép kết quả của bạn trong C, bạn đang sử dụng thư viện SHA nào? OpenSSL đề xuất các chức năng SHA1_* nhưng nói rằng SHA_* được bao gồm cho khả năng tương thích. Hai cho kết quả khác nhau đối với tôi, vì vậy nếu bạn đang so sánh để Trăn SHA1, bạn nên sử dụng 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; 
} 

Cung cấp:

d2 04 00 00 
7b08e025e311c3dfcf5179b67c0fdc08e73de261 

nào cho thấy rằng bạn đang đóng gói byte trong sai để thực hiện python của bạn. Nó nên là:

>>> import hashlib 
>>> hashlib.sha1(b'\xd2\x04\x00\x00').hexdigest() 
'7b08e025e311c3dfcf5179b67c0fdc08e73de261' 
>>> hashlib.sha1(bytearray(unpack('>4B', pack('I', 1234)))).hexdigest() 
'7b08e025e311c3dfcf5179b67c0fdc08e73de261' 

(Lưu ý không > ở phía trước của I) mà phù hợp với shasum trên.

Để tham khảo, nếu tôi sử dụng SHA_* chức năng tôi nhận được

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 

Mà dường như đồng ý với SHA ("-0 SHA") giá trị bằng Python:

>>> hashlib.new('sha', b'\xd2\x04\x00\x00').hexdigest() 
'3e491ac1d065d6d666e5e216e0cddf60fcb5be86' 
+0

Cảm ơn câu trả lời của bạn. Tôi đã sử dụng SHA từ mã Android. https://github.com/android/platform_system_core/blob/master/libmincrypt/sha.c. Nhưng thật lạ khi chuỗi SHA khớp với nhau. –

+0

Và 'hashlib.sha1 (bytearray (giải nén ('> 4B', gói ('I', 1234)))). Hexdigest()' là hàm đúng để làm tích hợp trong python? Cảm ơn. –

1

Nó có thể là mã của bạn chuyển đổi thành hex để in. Lưu ý rằng không bao lâu băm của bạn dài 40 ký tự? Hãy thử sử dụng phương thức to_hex() của tôi bên dưới.

python ==> '7110eda4d09e062aa5e4a390b0a572ac0d2c0220' 
string result: 7110eda4d09e62aa5e4a390b0a572acd2c220 
integer result: c7f07b846cc46631c2079cdd7179afdd783d643 

Tôi cũng không thể tạo lại kết quả C của bạn. Dưới đây là một phiên bản 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; 
} 

và đây là phiên bản 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; 
} 

rằng tập tin là trong system/core/libmincrypt và biên soạn với cc -I../include -o sha_test sha_test.c sha.c

cả hai chương trình mang lại kết quả tương tự

SHA1("1234") = 7110eda4d09e062aa5e4a390b0a572ac0d2c0220 
1234 LE =  d2040000 
SHA1(1234 LE) = 7b08e025e311c3dfcf5179b67c0fdc08e73de261 
1234 BE =  000004d2 
SHA1(1234 BE) = ac9928e78cf6ea117451ecd6654fea2adae73e21 
+1

Xin lỗi, mã thử nghiệm của tôi có một số vấn đề, n được thay đổi. Sau khi sửa lỗi này, SHA được liên kết với mã C. Cảm ơn tất cả các bạn –

2
digest = sha1.hexdigest() 
digest_int = int(digest,16) 
+0

Mặc dù mã này có thể trả lời câu hỏi, cung cấp ngữ cảnh bổ sung về cách thức và/hoặc lý do giải thích vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời. –