Pergunta

Tudo bem, este está me confundindo um pouco.

a seguinte função codifica uma string em base 64

void Base64Enc(const unsigned char *src, int srclen, unsigned char *dest)
{
    static const unsigned char enc[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    unsigned char *cp;
    int i;

    cp = dest;
    for(i = 0; i < srclen; i += 3) 
    {
      *(cp++) = enc[((src[i + 0] >> 2))];
      *(cp++) = enc[((src[i + 0] << 4) & 0x30)
                    | ((src[i + 1] >> 4) & 0x0f)];
      *(cp++) = enc[((src[i + 1] << 2) & 0x3c)
                    | ((src[i + 2] >> 6) & 0x03)];
      *(cp++) = enc[((src[i + 2]     ) & 0x3f)];
    }
    *cp = '\0';
    while (i-- > srclen)
      *(--cp) = '=';

    return;
}

Agora, na função de chamada Base64Enc () eu tenho:

unsigned char *B64Encoded;

Que é o argumento que passar para unsigned char * dest na função de codificação de base 64. Eu tentei diferentes inicializações de mallocs para NULL para outra inicialização. Não importa o que eu faço, eu sempre recebo uma exceção e se eu não inicialize-o, em seguida, o compilador (VS2005 compilador C) lança um aviso a dizer-me que não foi inicializado. Se eu executar esse código com a variável inicializada-un às vezes funciona e alguns outros não. Como faço para inicializar esse ponteiro e passá-lo para a função?

Foi útil?

Solução

Você precisa alocar buffer grande o suficiente para conter o resultado codificado. Ou alocá-lo na pilha, como este:

unsigned char B64Encoded[256]; // the number here needs to be big enough to hold all possible variations of the argument

Mas é fácil de causa tampão de estouro de pilha alocando muito pouco espaço usando esta abordagem. Seria muito melhor se você alocá-lo na memória dinâmica:

int cbEncodedSize = srclen * 4 / 3 + 1;  // cbEncodedSize is calculated from the length of the source string
unsigned char *B64Encoded = (unsigned char*)malloc(cbEncodedSize);

Não se esqueça de liberar () buffer alocado depois que você fez.

Outras dicas

Parece que você iria querer usar algo como isto:

// allocate 4/3 bytes per source character, plus one for the null terminator
unsigned char *B64Encoded = malloc(srclen*4/3+1);

Base64Enc(src, srclen, B64Encoded);

Seria bom se você forneceu o erro.

eu posso, com a sua função acima, para este sucesso:

int main() {
    unsigned char *B64Encoded;
    B64Encoded = (unsigned char *) malloc (1000);
    unsigned char *src = "ABC";
    Base64Enc(src, 3, B64Encoded);

}

Você definitivamente necessidade de espaço malloc para os dados. Você também precisa malloc mais espaço do que src (1/4 mais eu acredito).

Uma base 64 cadeia codificada tem quatro bytes por três bytes cadeia no-dados, por isso, se srclen é de 300 bytes (ou caracteres), o comprimento para as base64 cadeia codificada é 400.

Wikipedia tem uma breve mas muito bom artigo sobre ele.

Assim, o arredondamento para cima srclen à tupla mais próximo de três, dividido por três, vezes quatro deve ser memória exatamente o suficiente.

Eu vejo um problema em seu código no fato de que ele pode acessar o byte após o caractere nulo à direita, por exemplo, se o comprimento da corda é um caractere. O comportamento é então indefinido e pode resultar em uma excepção lançada se tampão de controlo de limite é activado.

Isto pode explicar a mensagem relacionada com o acesso à memória não inicializada.

Você deve então alterar o código para que você lidar com os caracteres à direita separadamente.

int len = (scrlen/3)*3;
for( int i = 0; i < len; i += 3 )
{
  // your current code here, it is ok with this loop condition.
}

// Handle 0 bits padding if required
if( len != srclen )
{
   // add new code here
}

...

PS: Aqui está uma página da Wikipedia que descreve Base64 codificação .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top