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; }