Study/C Language

Comparison : base64 encoding & decoding program

imaginefuture-1 2025. 3. 12. 00:40

 

빡공팟에서 c언어 공부하다가 base64 encoding decoding program 소스코드 작업중 

드림핵 요 문제 보고 소스 최적화랑 buffer 개념 확실히 와닿음.

 

c언어 책 삼일일만에 400페이지 읽기는 무리였다....200페이지 읽은 나에게 칭찬을 하자

과제 폭탄! 언제 책 다 읽어 엉엉..c언어만 진득히 파고싶어도 바로 파이썬 코드 짜야하죠~ 껄껄

 

최대한 시간 쪼개서 공부해야지!! 책은 잘못없다...따라가지못하는..한번에 이해못하는 내 머리가 문제다 

 

 

아래가 내가 지피티랑 같이 짠 코드

#include <stdio.h>
#include <string.h>

// Base64 테이블
const char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// Base64 디코딩 테이블
int base64_reverse_table[256];
// Base64 디코딩 테이블 초기화
void init_base64_reverse_table() {
    for (int i = 0; i < 256; i++) base64_reverse_table[i] = -1;
    for (int i = 0; i < 64; i++) base64_reverse_table[(int)base64_table[i]] = i;
}
// Base64 인코딩 함수
void base64_encode(const char *input, char *output, int len) {
    int i, j = 0;
    for (i = 0; i < len; i += 3) {
        unsigned int octet_a = (i < len) ? input[i] : 0;
        unsigned int octet_b = (i + 1 < len) ? input[i + 1] : 0;
        unsigned int octet_c = (i + 2 < len) ? input[i + 2] : 0;

        unsigned int triple = (octet_a << 16) | (octet_b << 8) | octet_c;

        output[j++] = base64_table[(triple >> 18) & 0x3F];
        output[j++] = base64_table[(triple >> 12) & 0x3F];
        output[j++] = (i + 1 < len) ? base64_table[(triple >> 6) & 0x3F] : '=';
        output[j++] = (i + 2 < len) ? base64_table[triple & 0x3F] : '=';
    }
    output[j] = '\0';  // 문자열 종료
}
// Base64 디코딩 함수
void base64_decode(const char *input, char *output, int len) {
    int i, j = 0;
    unsigned int sixbit_a, sixbit_b, sixbit_c, sixbit_d;
    unsigned int triple;
    
    // 유효한 Base64 길이 확인 (4의 배수여야 함)
    if (len % 4 != 0) {
        printf("Invalid Base64 input length!\n");
        return;
    }

    for (i = 0; i < len;) {
        // 패딩(`=`)이 오면 0으로 변환 & 디코딩된 바이트 수 줄이기
        sixbit_a = base64_reverse_table[(int)input[i++]];
        sixbit_b = base64_reverse_table[(int)input[i++]];
        sixbit_c = (input[i] == '=') ? 0 : base64_reverse_table[(int)input[i++]];
        sixbit_d = (input[i] == '=') ? 0 : base64_reverse_table[(int)input[i++]];

        // 잘못된 문자 확인
        if (sixbit_a == -1 || sixbit_b == -1 || sixbit_c == -1 || sixbit_d == -1) {
            printf("Invalid Base64 character detected!\n");
            return;
        }

        // 24비트 조합
        triple = (sixbit_a << 18) | (sixbit_b << 12) | (sixbit_c << 6) | sixbit_d;

        // 패딩이 있는 경우 바이트 개수 조정
        if (input[i - 2] == '=') {
            output[j++] = (triple >> 16) & 0xFF;
        } else if (input[i - 1] == '=') {
            output[j++] = (triple >> 16) & 0xFF;
            output[j++] = (triple >> 8) & 0xFF;
        } else {
            output[j++] = (triple >> 16) & 0xFF;
            output[j++] = (triple >> 8) & 0xFF;
            output[j++] = triple & 0xFF;
        }
    }
    output[j] = '\0';  // 문자열 종료
}
// 메인 프로그램
int main() {
    int choice;
    char input[1000], output[1500];  // 입력과 출력을 위한 버퍼

    // Base64 테이블 초기화
    init_base64_reverse_table();

        printf("\n>>> 1. Base64 encoding\n");
        printf(">>> 2. Base64 decoding\n");
        printf("#Input: ");
        
        if (scanf("%d", &choice) != 1) {
            printf("Invalid input. Please enter 1 or 2.\n");
            while (getchar() != '\n');  // 입력 버퍼 비우기

        }
        getchar();  // 개행 문자 제거

        if (choice == 1) {
            printf("#Input2 ");
            fgets(input, sizeof(input), stdin);
            input[strcspn(input, "\n")] = '\0';  // 개행 문자 제거

            base64_encode(input, output, strlen(input));
            printf(">>> %s\n", output);
        }
        else if (choice == 2) {
            printf("#Input2 ");
            fgets(input, sizeof(input), stdin);
            input[strcspn(input, "\n")] = '\0';  // 개행 문자 제거

            base64_decode(input, output, strlen(input));
            printf(">>> %s\n", output);
        }
        else {
            printf("Invalid option. Try again.\n");
    }
    return 0;
}

 


https://imaginefuture-1.tistory.com/385

 

[176] IT 비전공자 [dreamhack] [CodeEngn] Malware L05문제풀기

int Malware_L05(char *StartOfData,char *Output,int SizeOfData){ int encoded=0,i,l=0; char Table[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; long buffer,buffer2; do { ... for(i=3;i>=0;i--,l++) { buffer2=buffer; buffer2 &= 0x3f; *(O

imaginefuture-1.tistory.com

 

요게 드림핵에서 본 base64인코딩 buffer최적화된 고수분 코드인데, 지피티에게 요런스타일로

디코딩 코드도 추가해달라함.

int Malware_L05(char *StartOfData,char *Output,int SizeOfData)
{
	int encoded=0,i,l=0;
	char Table[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	long buffer,buffer2;
	do
	{
		...
		for(i=3;i>=0;i--,l++)
		{
			buffer2=buffer;
			buffer2 &= 0x3f;
			*(Output + i)=Table[buffer2];
			buffer>>=6;
		}
		Output+=4;
		encoded+=4;
		SizeOfData-=3;
		if(l==76 && SizeOfData>3)
		{
			*Output=0xd;
			Output++;
			*Output=0xa;
			Output++;
			encoded+=2;
			l=0;
		}
		...
		
	}while(SizeOfData!=0);
	return encoded;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Base64 테이블
char Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

// Base64 디코딩 테이블
int ReverseTable[256];

// Base64 디코딩 테이블 초기화
void init_base64_reverse_table() {
    for (int i = 0; i < 256; i++) ReverseTable[i] = -1;
    for (int i = 0; i < 64; i++) ReverseTable[(int)Table[i]] = i;
}

// Base64 인코딩 함수
int Base64_Encode(char *StartOfData, char *Output, int SizeOfData) {
    int encoded = 0, i, l = 0;
    long buffer, buffer2;

    while (SizeOfData > 0) {
        buffer = 0;
        for (i = 0; i < 3; i++) {
            buffer <<= 8;
            if (SizeOfData > 0) {
                buffer |= (unsigned char)*StartOfData++;
                SizeOfData--;
            }
        }

        for (i = 3; i >= 0; i--, l++) {
            buffer2 = buffer & 0x3F;
            Output[i] = Table[buffer2];
            buffer >>= 6;
        }

        Output += 4;
        encoded += 4;

        if (l == 76 && SizeOfData > 3) {
            *Output = '\r';
            Output++;
            *Output = '\n';
            Output++;
            encoded += 2;
            l = 0;
        }
    }

    // 패딩 추가 (남은 데이터 처리)
    while (encoded % 4) {
        *Output++ = '=';
        encoded++;
    }

    *Output = '\0'; // 문자열 종료
    return encoded;
}

// Base64 디코딩 함수
void Base64_Decode(char *StartOfData, char *Output, int SizeOfData) {
    int decoded = 0, i;
    long buffer;
    int pad = 0;

    // 패딩 개수(`=` 개수) 확인
    if (SizeOfData >= 2 && StartOfData[SizeOfData - 1] == '=') pad++;
    if (SizeOfData >= 2 && StartOfData[SizeOfData - 2] == '=') pad++;

    while (SizeOfData > 0) {
        buffer = 0;
        int valid_bytes = 0;

        for (i = 0; i < 4; i++) {
            if (SizeOfData == 0) break;
            char c = *StartOfData++;
            if (c == '=') break;
            buffer = (buffer << 6) | ReverseTable[(int)c];
            SizeOfData--;
            valid_bytes++;
        }

        // 3바이트 단위로 변환 (패딩 처리)
        if (valid_bytes > 1) Output[decoded++] = (char)((buffer >> 16) & 0xFF);
        if (valid_bytes > 2) Output[decoded++] = (char)((buffer >> 8) & 0xFF);
        if (valid_bytes > 3) Output[decoded++] = (char)(buffer & 0xFF);
    }

    Output[decoded] = '\0'; // 문자열 종료
}

// 메인 함수 (인코딩 & 디코딩 선택 가능)
int main() {
    int choice;
    char input[1000], output[1500];  // 입력과 출력을 위한 버퍼

    // Base64 테이블 초기화
    init_base64_reverse_table();

    while (1) {
        printf("\n>>> 1. Base64 encoding\n");
        printf(">>> 2. Base64 decoding\n");
        printf(">>> 3. Exit\n");
        printf("#Input: ");

        if (scanf("%d", &choice) != 1) {
            printf("Invalid input. Please enter 1, 2, or 3.\n");
            while (getchar() != '\n');  // 입력 버퍼 비우기
            continue;
        }
        getchar();  // 개행 문자 제거

        if (choice == 3) break;

        printf("#Input: ");
        fgets(input, sizeof(input), stdin);
        input[strcspn(input, "\n")] = '\0';  // 개행 문자 제거

        if (choice == 1) {
            Base64_Encode(input, output, strlen(input));
            printf(">>> Encoded: %s\n", output);
        } else if (choice == 2) {
            Base64_Decode(input, output, strlen(input));
            printf(">>> Decoded: %s\n", output);
        } else {
            printf("Invalid option. Try again.\n");
        }
    }

    return 0;
}

 

 

크..역시 코드는 최적화가 맞지~

 

확실히 책 반만 봤더니 반쪽짜리 코드 나왔다...엉엉 저도 최적화하고싶어요 ㅠㅠ