SHA1 hexdigest为long

时间:2012-07-31 16:22:29

标签: c d bigint

我有这个Python代码(hexdigest是一个SHA1):

d = long(hexdigest, 16)
if d >> 159:
    return "-%x" % ((-d) & (2**160-1))
return "%x" % d

我需要将此代码翻译成D.我尝试了几件事:

  • to!long(hexdigest,16) - 因溢出失败(对于ulong而言太大)
  • std.BigInt不支持二进制&

你怎么会在D?我将此问题标记为C相关,因为C解决方案也适用于D。

2 个答案:

答案 0 :(得分:1)

此代码看起来像NOP。您正在解析一个20字节数的SHA1 hexdigest。它永远不会超过160位,因此d>>160始终为0.因此,您只需以相同的格式重新格式化hexdigest。如果有的话,我猜你会丢掉前导零。

我很惊讶D std.BigInt没有提供位操作(&|^)。自己写吧?不能那么难。

答案 1 :(得分:0)

所以你想要一个从无符号到有符号2的补码的十六进制到十六进制的转换。你有没有意识到你可以逐位数字?输入字符串中的每个数字加上输出字符串中的对应数字等于0xf,除了最后一个数字,它是0x10。对于这个问题,任何类型的bigint算法都是过度的。

C中的演示(注意:这不会删除前导零)

#include <stdio.h>
#include <string.h>

static int fromhex(char dig)
{
  return dig >= '0' && dig <= '9' ? dig - '0'      :
         dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 :
         dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
         -1;
}

int main(int argc, char **argv)
{
  if(argc!=2 ||
     strlen(argv[1])!=40 ||
     strspn(argv[1], "0123456789abcdefABCDEF")!=40)
  {
    fprintf(stderr, "Usage: %s sha1hex\n", argv[0]);
    return 1;
  }
  if(strchr("01234567", argv[1][0])) {
    puts(argv[1]);
  } else {
    int i;
    putchar('-');
    for(i=0;i<39;++i)
      printf("%x", 15 - fromhex(argv[1][i]));
    printf("%x\n", 16 - fromhex(argv[1][i]));
  }
  return 0;
}