all repos — cryptopals-challenges @ e6f5696c7333ca99aff8332dcbe06dcafc31008b

cryptopals-challenges

set1/src/base64.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

/*
 * base64.c: reads in raw bytes and converts to/outputs in base64 format
 * x1phosura 2022
 */

#define BUF_LEN 4096

#define b64_output putchar
//#define b64_output b64_out_debug

size_t out_index = 0;
uint8_t out_buf[BUF_LEN];

void b64_out_debug(char c)
{
	printf("Using '%c' from base64 alphabet\n", c);
	out_buf[out_index] = c; // TODO: check out_index
	++out_index;
}

char *b64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";


int main()
{
	int8_t c;
	uint8_t tmp = 0, alph_index = 0, spoke = 0;
	
	while ((c = getchar()) != EOF) {
		switch (spoke) {
		case 0:
			alph_index = c >> 2;              // get last 6 bits
			tmp = (c & 0x03) << 4;            // extract last 2 bits
			break;
		case 1:
			alph_index = c >> 4;              // get last 4 bits
			alph_index += tmp;
			tmp = (c & 0x0f) << 2;
			break;
		case 2:
			alph_index = tmp;
			alph_index += c >> 6;
			b64_output(b64_alphabet[alph_index]);
			alph_index = c & 0x3f;
			break;
		}
		b64_output(b64_alphabet[alph_index]);
		spoke = (spoke + 1) % 3;
	}

	if (spoke == 1) {
		alph_index = tmp;
		b64_output(b64_alphabet[alph_index]);
		b64_output('=');
		b64_output('=');
	} else if (spoke == 2) {
		alph_index = tmp;
		b64_output(b64_alphabet[alph_index]);
		b64_output('=');
	}

	putchar('\n');

	return EXIT_SUCCESS;
}