Pregunta

Estoy tratando de utilizar las funciones de BN_ * OpenSSL. Específicamente, tengo el siguiente código:

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

Sin embargo, cuando hago esto, no consigo una serie de unos y ceros. En su lugar se imprime "42 in binary is *". Por lo que yo puedo decir, y desde el muy número limitado de ejemplos disponibles en la web que he comparó esto con, he implementado esto correctamente.

¿Alguna idea de por qué no está funcionando?

¿Fue útil?

Solución

BN_bn2bin no crea una cadena imprimible - en su lugar, se crea una representación que es verdaderamente binario (es decir, una secuencia de bits). Más específicamente, se createas una representación big-endian del número. Desde 42 encaja en un byte, se obtiene una 0x2a bytes, que es "*" en ASCII.

Si desea una representación 0/1, es necesario iterar sobre todos los bytes, y no la impresión de sí mismo (por ejemplo, con el cambio o una tabla de búsqueda).

Otros consejos

Aquí hay un código que se convierte en realidad la salida BN_bn2bin en una cadena imprimible al igual que la salida de BN_bn2dec y BN_bn2hex. Está en una biblioteca NodeJS pero está escrito en C ++ para la velocidad. Me llevó todo el día y probablemente no es óptima (porque no he escrito ningún código C ++ desde el primer año de uni). Pero pasa un montón de pruebas de unidad, así que sé que funciona!

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);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top