mirror of
https://github.com/sigmasternchen/CShore
synced 2025-03-15 08:08:56 +00:00
added base64 encoder/decoder
This commit is contained in:
parent
c84a75a09e
commit
f9670860df
2 changed files with 115 additions and 0 deletions
108
src/base64.c
Normal file
108
src/base64.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
static unsigned char charTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static unsigned char inverseTable[256];
|
||||
|
||||
__attribute__((constructor)) static void buildInverseTable() {
|
||||
memset(inverseTable, 0x80, 256);
|
||||
|
||||
size_t tableLength = strlen(charTable);
|
||||
for (unsigned int i = 0; i < tableLength; i++) {
|
||||
inverseTable[charTable[i]] = i;
|
||||
}
|
||||
inverseTable['='] = 0;
|
||||
}
|
||||
|
||||
char* base64_encode(const char* decoded) {
|
||||
size_t length = strlen(decoded) * 4 / 3 + 4;
|
||||
char* encoded = malloc(length + 1);
|
||||
if (encoded == NULL) {
|
||||
return encoded;
|
||||
}
|
||||
|
||||
size_t i = 0, j = 0;
|
||||
|
||||
while(length - j >= 3) {
|
||||
encoded[j++] = charTable[ decoded[i + 0] >> 2];
|
||||
encoded[j++] = charTable[((decoded[i + 0] & 0x03) << 4) | (decoded[i + 1] >> 4)];
|
||||
encoded[j++] = charTable[((decoded[i + 1] & 0x0f) << 2) | (decoded[i + 2] >> 6)];
|
||||
encoded[j++] = charTable[ decoded[i + 2] & 0x3f];
|
||||
i += 3;
|
||||
}
|
||||
|
||||
if (length - j > 0) {
|
||||
encoded[j++] = charTable[decoded[i] >> 2];
|
||||
if (length - i == 1) {
|
||||
encoded[j++] = charTable[(decoded[i] & 0x03) << 4];
|
||||
encoded[j++] = '=';
|
||||
} else {
|
||||
encoded[j++] = charTable[((decoded[i] & 0x03) << 4) | (decoded[i + 1] >> 4)];
|
||||
encoded[j++] = charTable[(decoded[i + 1] & 0x0f) << 2];
|
||||
}
|
||||
encoded[j++] = '=';
|
||||
}
|
||||
|
||||
encoded[j++] = '\0';
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
char* base64_decode(const char* encoded) {
|
||||
size_t length = strlen(encoded);
|
||||
size_t count = 0;
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (inverseTable[encoded[i]] != 0x80) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0 || count % 4 != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* decoded = malloc(count / 4 * 3);
|
||||
if (decoded == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pad = 0;
|
||||
unsigned char block[4];
|
||||
|
||||
count = 0;
|
||||
for (size_t i = 0, j = 0; i < length; i++) {
|
||||
unsigned char tmp = inverseTable[encoded[i]];
|
||||
if (tmp == 0x80) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (encoded[i] == '=') {
|
||||
pad++;
|
||||
}
|
||||
|
||||
block[count++] = tmp;
|
||||
if (count == 4) {
|
||||
decoded[j++] = (block[0] << 2) | (block[1] >> 4);
|
||||
decoded[j++] = (block[1] << 4) | (block[2] >> 2);
|
||||
decoded[j++] = (block[2] << 6) | (block[3]);
|
||||
count = 0;
|
||||
if (pad == 1) {
|
||||
j--;
|
||||
break;
|
||||
} else if (pad == 2) {
|
||||
j -= 2;
|
||||
break;
|
||||
} else if (pad > 0) {
|
||||
free(decoded);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return decoded;
|
||||
}
|
7
src/base64.h
Normal file
7
src/base64.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef BASE64_H_
|
||||
#define BASE64_H_
|
||||
|
||||
char* base64_encode(const char*);
|
||||
char* base64_decode(const char*);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue