Mr. Anderson l33t
Joined: 22 Apr 2004 Posts: 762
|
Posted: Mon Dec 27, 2021 6:50 pm Post subject: Base45-Implementierung in C |
|
|
Da ich im Portage Tree keine Base45-Implementierung gefunden habe, die sich als unmittelbar als kleines Werkzeug in einer Shell verwenden lässt, habe ich eine in C geschrieben. Hier ist sie, für den Fall, dass sonst noch jemand so etwas sucht:
Code: | /* draft-faltstrom-base45-08 */
#include <stdio.h>
#include <string.h>
#define ENC_SIZE 3
#define NAT_SIZE 2
#define XX (unsigned char) 0xFF
#define XX3 XX,XX,XX
#define XX4 XX3,XX
#define XX6 XX3,XX3
#define XX32 XX6,XX6,XX6,XX6,XX4,XX4
#define XX33 XX32,XX
#define XX165 XX33,XX33,XX33,XX33,XX33
unsigned char enc_table[] = {
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J',
'K','L','M','N','O','P','Q','R','S','T',
'U','V','W','X','Y','Z',' ','$','%','*',
'+', '-', '.', '/', ':'
};
unsigned char dec_table[] = {
XX32, 36, XX3, 37, 38, XX4, 39, 40, XX, 41, 42, 43, 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 44, XX6, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, XX165
};
int decode(FILE *in, FILE *out) {
/*
char dec_table[256];
memset(dec_table, 0xFF, 256);
int i;
for (i = 0; i < 45; i++) {
dec_table[enc_table[i]] = i;
}
*/
unsigned char buf_in[ENC_SIZE];
unsigned char buf_out[NAT_SIZE];
size_t read = fread(buf_in, 1, ENC_SIZE, in);
while (read == 3) {
unsigned char digit0 = dec_table[buf_in[0]];
unsigned char digit1 = dec_table[buf_in[1]];
unsigned char digit2 = dec_table[buf_in[2]];
unsigned int value;
if ((digit0 > 44) || (digit1 > 44) || (digit2 > 44)) {
fprintf(stderr, "garbage in input\n");
return -1;
}
if ((value = digit0 + 45 * (digit1 + 45 * digit2)) > 65535) {
fprintf(stderr, "value out of range %u\n", value);
return -1;
}
buf_out[0] = (value >> 8) & 0xFF;
buf_out[1] = value & 0xFF;
fwrite(buf_out, 1, NAT_SIZE, out);
if (ferror(out) != 0) {
return -1;
}
read = fread(buf_in, 1, ENC_SIZE, in);
}
if (read == 2) {
unsigned char digit0 = dec_table[buf_in[0]];
unsigned char digit1 = dec_table[buf_in[1]];
unsigned int value;
if ((digit0 > 44) || (digit1 > 44)) {
printf("garbage in input\n");
return -1;
}
if ((value = digit0 + 45 * digit1) > 255) {
fprintf(stderr, "value out of range %u\n", value);
return -1;
}
buf_out[0] = value;
fwrite(buf_out, 1, 1, out);
if (ferror(out) != 0) {
return -1;
}
}
fwrite("\n", 1, 1, out);
if (ferror(in) != 0) {
return ferror(in);
}
if (feof(in) == 0) {
return -1;
}
return 0;
}
int encode(FILE *in, FILE *out) {
unsigned char buf_in[NAT_SIZE];
unsigned char buf_out[ENC_SIZE];
size_t read = fread(buf_in, 1, NAT_SIZE, in);
while (read == 2) {
unsigned int value = (buf_in[0]<<8) + buf_in[1];
buf_out[0] = enc_table[value % 45];
value /= 45;
buf_out[1] = enc_table[value % 45];
value /= 45;
buf_out[2] = enc_table[value];
fwrite(buf_out, 1, ENC_SIZE, out);
if (ferror(out) != 0) {
return -1;
}
read = fread(buf_in, 1, NAT_SIZE, in);
}
if (read == 1) {
unsigned int value = buf_in[0];
buf_out[0] = enc_table[value % 45];
value /= 45;
buf_out[1] = enc_table[value];
fwrite(buf_out, 1, 2, out);
if (ferror(out) != 0) {
return -1;
}
}
fwrite("\n", 1, 1, out);
if (ferror(in) != 0) {
return ferror(in);
}
if (feof(in) == 0) {
return -1;
}
return 0;
}
int main(int argc, char **argv) {
if (argc > 1 && (strcmp("-d", argv[1]) == 0)) {
return decode(stdin, stdout);
} else {
return encode(stdin, stdout);
}
}
|
Enthält vllt. Fehler und kann sicher noch verbessert werden.
Lizenz völlig egal. |
|