|
|
| Rad 4: |
Rad 4: |
|
| |
|
| = Implementation = | | = Implementation = |
|
| |
| = C =
| |
|
| |
| <pre>
| |
| #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;
| |
| }
| |
| </pre>
| |
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