Base24
Från Täpp-Anders
Bakgrund
Base24 är inte en standardkodning och den är lite mer komplex än de som baseras på ett jämt antal oktetter som base32 samt base64 men det har en fördel också, vi använder bara stora bokstäver A-X.
Implementation
C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// BASE24 kodningstabell (A-X)
static const char base24_table[] = "ABCDEFGHIJKLMNOPQRSTUVWX";
// Funktion för BASE24 kodning
char* base24_encode(const unsigned char* input, size_t length) {
// Beräkna antal output-tecken: ungefär 8 bitar per 4.585 bitar (log2(24))
size_t output_length = (length * 8 + 4) / 5; // Ungefärlig uppskattning
char* encoded = malloc(output_length + 1);
if (encoded == NULL) return NULL;
unsigned long long buffer = 0;
int bits_left = 0;
size_t j = 0;
for (size_t i = 0; i < length; i++) {
buffer = (buffer << 8) | input[i];
bits_left += 8;
while (bits_left >= 5) {
int shift = bits_left - 5;
unsigned char value = (buffer >> shift) & 0x1F; // Ta 5 bitar
if (value >= 24) value = 23; // Begränsa till 0-23
encoded[j++] = base24_table[value];
bits_left -= 5;
buffer &= (1ULL << bits_left) - 1; // Rensa använda bitar
}
}
// Hantera resterande bitar
if (bits_left > 0) {
buffer <<= (5 - bits_left);
unsigned char value = (buffer & 0x1F);
if (value >= 24) value = 23;
encoded[j++] = base24_table[value];
}
encoded[j] = '\0';
return encoded;
}
// Funktion för BASE24 avkodning
unsigned char* base24_decode(const char* input, size_t* output_length) {
size_t input_length = strlen(input);
// Skapa lookup-tabell
unsigned char decode_table[256] = {0};
for (int i = 0; i < 24; i++) {
decode_table[(unsigned char)base24_table[i]] = i;
}
unsigned long long buffer = 0;
int bits_left = 0;
size_t decoded_size = (input_length * 5 + 7) / 8; // Uppskattad maxstorlek
unsigned char* decoded = malloc(decoded_size);
if (decoded == NULL) return NULL;
size_t j = 0;
for (size_t i = 0; i < input_length; i++) {
unsigned char value = decode_table[(unsigned char)input[i]];
buffer = (buffer << 5) | value;
bits_left += 5;
while (bits_left >= 8) {
int shift = bits_left - 8;
decoded[j++] = (buffer >> shift) & 0xFF;
bits_left -= 8;
buffer &= (1ULL << bits_left) - 1;
}
}
*output_length = j;
return decoded;
}
// Testprogram
int main() {
const char* original = "Hello World!";
size_t input_length = strlen(original);
// Kodning
char* encoded = base24_encode((const unsigned char*)original, input_length);
if (!encoded) {
printf("Kodningsfel\n");
return 1;
}
// Avkodning
size_t decoded_length;
unsigned char* decoded = base24_decode(encoded, &decoded_length);
if (!decoded) {
printf("Avkodningsfel\n");
free(encoded);
return 1;
}
// Skriv ut resultat
printf("Original: %s\n", original);
printf("BASE24: %s\n", encoded);
printf("Decoded: %.*s\n", (int)decoded_length, decoded);
// Frigör minne
free(encoded);
free(decoded);
return 0;
}