代码之家  ›  专栏  ›  技术社区  ›  Dave DeLong

openssl的bn_bn2bin函数有问题

  •  2
  • Dave DeLong  · 技术社区  · 15 年前

    我正在尝试在OpenSSL中使用bn_u*函数。具体来说,我有以下代码:

    #import <openssl/bn.h>
    BIGNUM * num = BN_new();
    BN_set_word(num, 42);
    char * buffer = malloc((BN_num_bytes(num)+1) * sizeof(char));
    buffer[BN_num_bytes(num)] = '\0';
    int len = BN_bn2bin(num, buffer);
    printf("42 in binary is %s\n", buffer);
    

    但是,当我这样做的时候,我不会得到一串1和0。而是打印出来的 "42 in binary is *" .据我所知, 非常 在我比较过的网络上可用的示例数量有限,我已经正确地实现了这一点。

    你知道为什么它不起作用吗?

    2 回复  |  直到 9 年前
        1
  •  6
  •   Martin v. Löwis    15 年前

    BN_bn2bin 不创建可打印字符串-相反,它创建了一个真正的二进制表示(即位序列)。更具体地说,它创建了数字的大尾数表示。因为42适合一个字节,所以您得到一个字节0x2A,在ASCII中是“*”。

    如果需要0/1表示,则需要迭代所有字节,然后自己打印(例如,使用移位或查阅表)。

        2
  •  0
  •   MalcolmOcean    9 年前

    下面是一些代码,它实际上将 BN_bn2bin 输出到可打印字符串,就像输出 BN_bn2dec BN_bn2hex .它是在NoDEJS库中,但用C++编写的速度。我花了一整天的时间,可能不是最理想的(因为我从UNI的第一年就没有写过任何C++代码)。但是它通过了一系列的单元测试,所以我知道它是有效的!

    https://github.com/malcolmocean/node-bignum

    if (BN_is_zero(&bignum->bignum_)) {
      to = (char*) OPENSSL_malloc(2*sizeof(char));
      to[0] = '0';
      to[1] = '\0';
    } else {
      unsigned char *binary = (unsigned char*) OPENSSL_malloc(BN_num_bytes(&bignum->bignum_)*sizeof(unsigned char));
      int len = BN_bn2bin(&bignum->bignum_, binary);
      to = (char*) OPENSSL_malloc((len*8+2)*sizeof(char));
      int offset = 0;
      if (BN_is_negative(&bignum->bignum_)) {
        to[0] = '-';
        offset--;
      }
      unsigned char x = binary[0];
      while (!(x & 128) && x) {
        x = x << 1;
        offset++;
      }
      for (int i = 0; i < len; i++) {
        unsigned char bits = binary[i];
    
        int j=7;
        while(bits) {
          if (bits & 1) {
            to[8*i+j-offset] = '1';
          } else {
            to[8*i+j-offset] = '0';
          }
          bits = bits >> 1;
          j--;
        }
        if (i > 0) {
          while (j >= 0) {
            to[8*i+j-offset] = '0';
            j--;
          }
        }
      }
      to[8*len-offset] = '\0';
      OPENSSL_free(binary);
    }