Base32
Från Täpp-Anders
Hoppa till navigeringHoppa till sök
För bakgrundsinformation se Base64.
Implementation
C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// BASE32 kodningstabell
static const char base32_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
// Funktion för BASE32 kodning
char* base32_encode(const unsigned char* input, size_t length) {
// Beräkna utdatalängd: 8 tecken för varje 5 bytes
size_t output_length = 8 * ((length + 4) / 5);
char* encoded = malloc(output_length + 1);
if (encoded == NULL) return NULL;
size_t i = 0, j = 0;
unsigned long buffer = 0;
int bits_left = 0;
while (i < length || bits_left > 0) {
// Fyll buffert med upp till 5 bytes
if (bits_left < 5 && i < length) {
buffer = (buffer << 8) | input[i++];
bits_left += 8;
}
// Om vi har minst 5 bitar, ta ut ett BASE32-tecken
if (bits_left >= 5) {
int value = (buffer >> (bits_left - 5)) & 0x1F;
encoded[j++] = base32_table[value];
bits_left -= 5;
} else if (i >= length) {
// Padding för sista gruppen
encoded[j++] = '=';
bits_left = 0;
}
}
// Fyll på med padding till multipel av 8
while (j % 8 != 0) {
encoded[j++] = '=';
}
encoded[j] = '\0';
return encoded;
}
// Funktion för BASE32 avkodning
unsigned char* base32_decode(const char* input, size_t* output_length) {
size_t input_length = strlen(input);
if (input_length % 8 != 0) return NULL; // BASE32 måste vara multipler av 8
// Räkna faktiska databytes (exkludera padding)
size_t padding = 0;
for (int i = input_length - 1; i >= 0 && input[i] == '='; i--) {
padding++;
}
// Beräkna utdatalängd
*output_length = (input_length * 5) / 8 - padding;
unsigned char* decoded = malloc(*output_length);
if (decoded == NULL) return NULL;
// Skapa lookup-tabell
unsigned char decode_table[256] = {0};
for (int i = 0; i < 32; i++) {
decode_table[(unsigned char)base32_table[i]] = i;
}
unsigned long buffer = 0;
int bits_left = 0;
size_t j = 0;
for (size_t i = 0; i < input_length; i++) {
if (input[i] == '=') break;
buffer = (buffer << 5) | decode_table[(unsigned char)input[i]];
bits_left += 5;
if (bits_left >= 8) {
decoded[j++] = (buffer >> (bits_left - 8)) & 0xFF;
bits_left -= 8;
}
}
return decoded;
}
// Testprogram
int main() {
const char* original = "Hello World!";
size_t input_length = strlen(original);
// Kodning
char* encoded = base32_encode((const unsigned char*)original, input_length);
if (!encoded) {
printf("Kodningsfel\n");
return 1;
}
// Avkodning
size_t decoded_length;
unsigned char* decoded = base32_decode(encoded, &decoded_length);
if (!decoded) {
printf("Avkodningsfel\n");
free(encoded);
return 1;
}
// Skriv ut resultat
printf("Original: %s\n", original);
printf("BASE32: %s\n", encoded);
printf("Decoded: %.*s\n", (int)decoded_length, decoded);
// Frigör minne
free(encoded);
free(decoded);
return 0;
}