Question

Je suis en train d'utiliser les BN_ * fonctions OpenSSL. Plus précisément, j'ai le code suivant:

#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);

Cependant, quand je le fais, je ne reçois pas une chaîne de uns et de zéros. Au contraire, il imprime "42 in binary is *". Pour autant que je peux dire, et de très nombre limité d'exemples disponibles sur le web que j'ai comparé cela, je l'ai mis en œuvre cette correctement.

Toutes les idées pourquoi il ne fonctionne pas?

Était-ce utile?

La solution

BN_bn2bin ne crée pas une chaîne imprimable - au lieu, il crée une représentation qui est vraiment binaire (à savoir une séquence de bits). Plus précisément, il createas une représentation big-endian du nombre. Etant donné que 42 s'insère dans un octet, vous obtenez un octet 0x2a, qui est « * » en ASCII.

Si vous voulez une représentation 0/1, vous devez itérer sur tous les octets, et ne vous-même l'impression (par exemple avec décalage ou une table de consultation).

Autres conseils

Voici un code qui se fait la sortie de BN_bn2bin dans une chaîne imprimable comme la sortie de BN_bn2dec et BN_bn2hex. Il est dans une bibliothèque NodeJS mais il est écrit en C ++ pour la vitesse. Il m'a fallu toute la journée et est probablement pas optimale (parce que je ne l'ai pas écrit de code C ++ depuis la première année d'uni). Mais il passe un tas de tests unitaires, donc je sais que cela fonctionne!

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);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top