문제

좋아, 이건 나를 조금 당황하게했다.

다음 함수는 문자열을 기본 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;
}

이제 Base64enc () 호출 기능에서 다음과 같습니다.

unsigned char *B64Encoded;

기본 64 인코딩 함수에서 서명되지 않은 char *dest에 전달되는 주장입니다. Mallocs와 NULL, 다른 초기화에 이르기까지 다른 초기화를 시도했습니다. 내가 무엇을 하든지 예외가 발생하더라도 초기화되지 않으면 컴파일러 (vs2005 C 컴파일러)가 초기화되지 않았다는 경고를 던집니다. 이 소식이없는 변수 로이 코드를 실행하면 때때로 작동하고 다른 것이 작동하지 않습니다. 해당 포인터를 초기화하고 함수로 전달하는 방법은 무엇입니까?

도움이 되었습니까?

해결책

인코딩 된 결과를 포함 할만 큼 큰 버퍼를 할당해야합니다. 다음과 같이 스택에 할당하십시오.

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

그러나이 접근법을 사용하여 공간을 너무 적게 할당하여 스택 버퍼 오버 플로우를 쉽게 만듭니다. 동적 메모리에 할당하면 훨씬 나을 것입니다.

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

완료된 후에 할당 된 버퍼를 자유롭게하는 것을 잊지 마십시오.

다른 팁

다음과 같은 것을 사용하고 싶을 것 같습니다.

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

오류를 제공하면 도움이됩니다.

위의 기능으로 이것을 성공적으로 할 수 있습니다.

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

}

분명히 데이터를 위해 공간이 필요합니다. 또한 SRC보다 더 많은 공간을 낭만해야합니다 (1/4 더 믿습니다).

Base64 인코딩 된 문자열에는 3 바이트 당 4 바이트가 있는데 4 바이트가 있으므로 SRCLEN이 300 바이트 (또는 문자) 인 경우 Base64 인코딩 된 문자열의 길이는 400입니다.

위키 백과 그것에 대한 간단하지만 아주 좋은 기사가 있습니다.

따라서 SRCLEN을 3 개 중 가장 가까운 튜플로 반올림하는 것은 3, 4 번으로 나눈 것만으로는 정확히 메모리가되어야합니다.

예를 들어 스트링 길이가 하나의 숯 인 경우 트레일 널 숯 이후 바이트에 액세스 할 수 있다는 사실에서 코드에 문제가 있습니다. 그런 다음 동작이 정의되지 않아 버퍼 경계 검사가 활성화되면 예외가 발생할 수 있습니다.

이는 초기화되지 않은 메모리에 액세스하는 것과 관련된 메시지를 설명 할 수 있습니다.

그런 다음 후행 숯을 별도로 처리하도록 코드를 변경해야합니다.

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
}

...

추신 : 다음은 Wikipedia 페이지를 설명합니다 Base64 인코딩.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top