2

OpenSSL で BN_* 関数を使用しようとしています。具体的には、次のコードがあります。

#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 *"ます。私が知る限り、これを比較したウェブ上で入手可能な非常に限られた数の例から、私はこれを正しく実装しました。

それが機能しない理由はありますか?

4

2 に答える 2

6

BN_bn2bin印刷可能な文字列を作成しません。代わりに、真のバイナリ (つまり、一連のビット) の表現を作成します。より具体的には、数値のビッグエンディアン表現として作成します。42 は 1 バイトに収まるので、1 バイトの 0x2a が得られます。これは ASCII の「*」です。

0/1 表現が必要な場合は、すべてのバイトを反復処理し、自分で印刷する必要があります (たとえば、シフトまたはルックアップ テーブルを使用)。

于 2009-10-01T21:38:50.387 に答える
0

と の出力と同じように、実際にBN_bn2bin出力を印刷可能な文字列に変換するコードを次に示します。これは NodeJS ライブラリにありますが、速度を上げるために C++ で書かれています。一日中かかりましたが、おそらく最適ではありません (大学の最初の年から C++ コードを書いていないため)。しかし、それは一連の単体テストに合格しているので、動作することはわかっています!BN_bn2decBN_bn2hex

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);
}
于 2015-10-31T06:00:09.107 に答える