Add function to decode base64

This commit is contained in:
Dimitri Lozeve 2020-06-04 20:11:00 +02:00
parent b1c777d1ea
commit f3a8d9c74f
3 changed files with 62 additions and 3 deletions

View file

@ -37,6 +37,26 @@ static MunitResult test_hex_to_base64(const MunitParameter params[],
return MUNIT_OK; return MUNIT_OK;
} }
static MunitResult test_base64_decode(const MunitParameter params[],
void *data) {
(void)params;
(void)data;
const char *input = "TWFu";
unsigned char buf[512] = {0};
size_t len = base64_to_bytes(buf, input);
assert_string_equal((char *)buf, "Man");
assert_size(len, ==, 3);
const char *input2 = "WUVMTE9XIFNVQk1BUklORQ==";
memset(buf, 0, 512);
len = base64_to_bytes(buf, input2);
assert_string_equal((char *)buf, "YELLOW SUBMARINE");
assert_size(len, ==, 18); // the 2 = create two bytes of padding at the end
return MUNIT_OK;
}
static MunitResult test_frequency_score(const MunitParameter params[], static MunitResult test_frequency_score(const MunitParameter params[],
void *data) { void *data) {
(void)params; (void)params;
@ -73,6 +93,8 @@ static MunitTest test_suite_tests[] = {
NULL}, NULL},
{"/hex_to_base64", test_hex_to_base64, NULL, NULL, MUNIT_TEST_OPTION_NONE, {"/hex_to_base64", test_hex_to_base64, NULL, NULL, MUNIT_TEST_OPTION_NONE,
NULL}, NULL},
{"/base64_decode", test_base64_decode, NULL, NULL, MUNIT_TEST_OPTION_NONE,
NULL},
{"/frequency_score", test_frequency_score, NULL, NULL, {"/frequency_score", test_frequency_score, NULL, NULL,
MUNIT_TEST_OPTION_NONE, NULL}, MUNIT_TEST_OPTION_NONE, NULL},
{"/hamming", test_hamming, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL}, {"/hamming", test_hamming, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},

38
utils.c
View file

@ -36,10 +36,10 @@ size_t hex_to_bytes(unsigned char *out, const char hex[static 1]) {
return strlen(hex) / 2 + strlen(hex) % 2; return strlen(hex) / 2 + strlen(hex) % 2;
} }
char *bytes_to_base64(char *out, const unsigned char in[static 1], size_t len) {
static const char base64_table[65] = static const char base64_table[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *bytes_to_base64(char *out, const unsigned char in[static 1], size_t len) {
for (size_t i = 0; i < len - 2; i += 3) { for (size_t i = 0; i < len - 2; i += 3) {
size_t j = i / 3 * 4; size_t j = i / 3 * 4;
out[j] = base64_table[in[i] >> 2]; out[j] = base64_table[in[i] >> 2];
@ -50,6 +50,42 @@ char *bytes_to_base64(char *out, const unsigned char in[static 1], size_t len) {
return out; return out;
} }
size_t base64_to_bytes(unsigned char *out, const char *in) {
char decoding_table[256] = {0};
for (size_t i = 0; i < 64; ++i) {
decoding_table[(unsigned char)base64_table[i]] = i;
}
size_t in_length = strlen(in);
if (in_length % 4 != 0) {
return 0;
}
size_t i = 0;
for (size_t j = 0; j < in_length - 3;) {
unsigned char sextet1 =
in[j] == '=' ? 0 : decoding_table[(unsigned char)in[j]];
unsigned char sextet2 =
in[j + 1] == '=' ? 0 : decoding_table[(unsigned char)in[j + 1]];
unsigned char sextet3 =
in[j + 2] == '=' ? 0 : decoding_table[(unsigned char)in[j + 2]];
unsigned char sextet4 =
in[j + 3] == '=' ? 0 : decoding_table[(unsigned char)in[j + 3]];
out[i] = sextet1 << 2;
out[i] += sextet2 >> 4;
out[i + 1] = sextet2 << 4;
out[i + 1] += sextet3 >> 2;
out[i + 2] = sextet3 << 6;
out[i + 2] += sextet4;
j += 4;
i += 3;
}
return i;
}
double frequency_score(const char *buf, size_t len) { double frequency_score(const char *buf, size_t len) {
static const double english_freqs[27] = { static const double english_freqs[27] = {
0.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015, // A-G 0.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015, // A-G

View file

@ -6,6 +6,7 @@
unsigned char hex_to_byte(const char c); unsigned char hex_to_byte(const char c);
size_t hex_to_bytes(unsigned char *out, const char hex[static 1]); size_t hex_to_bytes(unsigned char *out, const char hex[static 1]);
char *bytes_to_base64(char *out, const unsigned char in[static 1], size_t len); char *bytes_to_base64(char *out, const unsigned char in[static 1], size_t len);
size_t base64_to_bytes(unsigned char *out, const char *in);
double frequency_score(const char *buf, size_t len); double frequency_score(const char *buf, size_t len);
unsigned int hamming(const char *s1, const char *s2); unsigned int hamming(const char *s1, const char *s2);