Pergunta

Eu estou tentando usar o BN_ * funções no OpenSSL. Especificamente, eu tenho o seguinte 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);

No entanto, quando eu faço isso, eu não receber uma série de uns e zeros. Em vez disso, imprime "42 in binary is *". Tanto quanto eu posso dizer, e para o muito número limitado de exemplos disponíveis na Web que eu tenho em comparação isso, eu tenho implementado isso corretamente.

Todas as ideias por que ele não está funcionando?

Foi útil?

Solução

BN_bn2bin não cria uma string de impressão - em vez disso, ele cria uma representação que é verdadeiramente binário (ou seja, uma sequência de bits). Mais especificamente, createas uma representação big-endian do número. Desde 42 se encaixa em um byte, você começa um 0x2a byte, que é "*" em ASCII.

Se você quiser uma representação 0/1, você precisa iterar sobre todos os bytes, e fazer a impressão de si mesmo (por exemplo, com a mudança ou uma tabela de pesquisa).

Outras dicas

Aqui está um código que realmente transforma a saída BN_bn2bin em uma seqüência de impressão, assim como a saída de BN_bn2dec e BN_bn2hex. É em uma biblioteca NodeJS mas é escrito em C ++ para a velocidade. Levou-me durante todo o dia e, provavelmente, não é o ideal (porque eu não tenho escrito qualquer código C ++ desde o primeiro ano de uni). Mas ele passa um monte de testes de unidade, então eu sei 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top