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