1
typedef union
{
    uint ui[4];
} md5hash;

void main(void)
{
    int opt;

    while ((opt = getopt(argc, argv, "c:t:s:h:")) != -1) {
        switch (opt) {
        case 'h':
            hash = optarg;
            break;
        default: /* '?' */
            exit(EXIT_FAILURE);
        }
    }

    md5hash hash;

    sscanf(hash, "%x%x%x%x", &hash.ui);
}

./program -h ffffffffffffffffffffffffffffffff

我想做上面的事情,但是 sscanf 不正确地接受 md5sum ......

4

2 回答 2

5
  1. 您似乎有两个称为哈希的变量,除了一个隐含在您的代码中。
  2. sscanf语句试图读hash回自身,但显然它不会找到任何十六进制数字。
  3. %x可能会在不同平台上加载不同大小的十六进制整数,因为您没有为每个字段指定要读取的任何特定长度。
  4. 您没有考虑机器字节序。

如果你确实有一个十六进制字符串,hashString那么你可以试试

int fieldsScanned = sscanf (hashString, "%8x%8x%8x%8x", &hash.ui[0], &hash.ui[1], &hash.ui[2], &hash.ui[3]);

if (fieldsScanned == 4)
{
    // MD5 sum is in hash variable.
}
于 2008-12-09T01:59:09.073 回答
0
int
parse_hex(char *s, unsigned char *hex, int len)
{
  int i, r = 0;

  len *= 2;
  for (i = 0; ; i++, s++)
    {
      if (*s == 0 && !(i & 1))
        return i / 2;
      if (i == len)
        {
          fprintf(stderr, "parsehex: string too long\n");
          //exit(1);
        }
      if (*s >= '0' && *s <= '9')
        r = (r << 4) | (*s - '0');
      else if (*s >= 'a' && *s <= 'f')
        r = (r << 4) | (*s - ('a' - 10));
      else if (*s >= 'A' && *s <= 'F')
        r = (r << 4) | (*s - ('a' - 10));
      else
        {
          fprintf(stderr, "parsehex: bad string\n");
          //exit(1);
        }
      if ((i & 1) != 0)
        {
          hex[i / 2] = r;
          r = 0;
        }
    }
}

void
parse_md5(char *s, unsigned char *md5)
{
  if (!*s)
    {
      memset(md5, 0, 16);
      return;
    }
  if (parse_hex(s, md5, 16) != 16)
    {
      fprintf(stderr, "parsemd5: bad md5\n");
      //exit(1);
    }
}

实际上,上面的 sscanf() 方法不起作用,它在双字中以相反的顺序读取字节。

于 2008-12-09T06:38:32.863 回答