簡體   English   中英

Python SHA1整數

[英]Python SHA1 Integer

我在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?

digest = sha1.hexdigest()
digest_int = int(digest,16)

我無法在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'

它可能是您的代碼轉換為十六進制打印。 請注意你的哈希值是多少都不是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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM