mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-30 13:35:09 +00:00
Working base32, atleast on linux
This commit is contained in:
parent
b14b23c936
commit
e6dc37f83a
178
encoding.c
178
encoding.c
@ -15,31 +15,117 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// For FreeBSD
|
// For FreeBSD
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char to_hex[] = "0123456789ABCDEF";
|
#define SPACING 63
|
||||||
|
#define ENC_CHUNK 8
|
||||||
|
#define RAW_CHUNK 5
|
||||||
|
|
||||||
|
static const char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ98765-";
|
||||||
|
static const char padder[] = " 1234";
|
||||||
|
static char reverse32[128];
|
||||||
|
static int reverse_init = 0;
|
||||||
|
|
||||||
|
/* Eat 5 bytes from src, write 8 bytes to dest */
|
||||||
|
static void
|
||||||
|
encode_chunk(char *dest, char *src)
|
||||||
|
{
|
||||||
|
unsigned char c;
|
||||||
|
|
||||||
|
*dest++ = base32[(*src & 0xF8) >> 3]; // 1111 1000 first byte
|
||||||
|
|
||||||
|
c = (*src++ & 0x07) << 2; // 0000 0111 first byte
|
||||||
|
c |= ((*src & 0xC0) >> 6); // 1100 0000 second byte
|
||||||
|
*dest++ = base32[(int) c];
|
||||||
|
|
||||||
|
*dest++ = base32[(*src & 0x3E) >> 1]; // 0011 1110 second byte
|
||||||
|
|
||||||
|
c = (*src++ & 0x01) << 4; // 0000 0001 second byte
|
||||||
|
c |= ((*src & 0xF0) >> 4); // 1111 0000 third byte
|
||||||
|
*dest++ = base32[(int) c];
|
||||||
|
|
||||||
|
c = (*src++ & 0x0F) << 1; // 0000 1111 third byte
|
||||||
|
c |= ((*src & 0x80) >> 7); // 1000 0000 fourth byte
|
||||||
|
*dest++ = base32[(int) c];
|
||||||
|
|
||||||
|
*dest++ = base32[(*src & 0x7C) >> 2]; // 0111 1100 fourth byte
|
||||||
|
|
||||||
|
c = (*src++ & 0x03) << 3; // 0000 0011 fourth byte
|
||||||
|
c |= ((*src & 0xE0) >> 5); // 1110 0000 fifth byte
|
||||||
|
*dest++ = base32[(int) c];
|
||||||
|
|
||||||
|
*dest++ = base32[*src++ & 0x1F]; // 0001 1111 fifth byte
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Eat 8 bytes from src, write 5 bytes to dest */
|
||||||
|
static void
|
||||||
|
decode_chunk(char *dest, char *src)
|
||||||
|
{
|
||||||
|
unsigned char c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!reverse_init) {
|
||||||
|
for (i = 0; i < 32; i++) {
|
||||||
|
c = base32[i];
|
||||||
|
reverse32[(int) c] = i;
|
||||||
|
}
|
||||||
|
reverse_init = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = reverse32[(int) *src++] << 3; // Take bits 11111 from byte 1
|
||||||
|
c |= (reverse32[(int) *src] & 0x1C) >> 2; // Take bits 11100 from byte 2
|
||||||
|
*dest++ = c;
|
||||||
|
|
||||||
|
c = (reverse32[(int) *src++] & 0x3) << 6; // Take bits 00011 from byte 2
|
||||||
|
c |= reverse32[(int) *src++] << 1; // Take bits 11111 from byte 3
|
||||||
|
c |= (reverse32[(int) *src] & 0x10) >> 4; // Take bits 10000 from byte 4
|
||||||
|
*dest++ = c;
|
||||||
|
|
||||||
|
c = (reverse32[(int) *src++] & 0xF) << 4; // Take bits 01111 from byte 4
|
||||||
|
c |= (reverse32[(int) *src] & 0x1E) >> 1; // Take bits 11110 from byte 5
|
||||||
|
*dest++ = c;
|
||||||
|
|
||||||
|
c = reverse32[(int) *src++] << 7; // Take bits 00001 from byte 5
|
||||||
|
c |= reverse32[(int) *src++] << 2; // Take bits 11111 from byte 6
|
||||||
|
c |= (reverse32[(int) *src] & 0x18) >> 3; // Take bits 11000 from byte 7
|
||||||
|
*dest++ = c;
|
||||||
|
|
||||||
|
c = (reverse32[(int) *src++] & 0x7) << 5; // Take bits 00111 from byte 7
|
||||||
|
c |= reverse32[(int) *src++]; // Take bits 11111 from byte 8
|
||||||
|
*dest++ = c;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
encode_data(char *buf, int len, int space, char *dest, char flag)
|
encode_data(char *buf, int len, int space, char *dest, char flag)
|
||||||
{
|
{
|
||||||
int final;
|
int final;
|
||||||
int write;
|
int write;
|
||||||
|
int realwrite;
|
||||||
|
int chunks;
|
||||||
|
int leftovers;
|
||||||
int i;
|
int i;
|
||||||
int t;
|
char encoded[255];
|
||||||
|
char padding[5];
|
||||||
#define CHUNK 31
|
char *pp;
|
||||||
// 31 bytes expands to 62 chars in domain
|
char *dp;
|
||||||
// We just use hex as encoding right now
|
char *ep;
|
||||||
|
|
||||||
write = space / 2; // use two chars per byte in encoding
|
|
||||||
write -= (write/CHUNK); // make space for parts
|
|
||||||
|
|
||||||
|
space -= space / SPACING;
|
||||||
|
chunks = (space - 1) / ENC_CHUNK;
|
||||||
|
while ((chunks + 1) * ENC_CHUNK + 1 > space) {
|
||||||
|
chunks--;
|
||||||
|
}
|
||||||
|
write = RAW_CHUNK * chunks;
|
||||||
write = MIN(write, len); // do not use more bytes than is available;
|
write = MIN(write, len); // do not use more bytes than is available;
|
||||||
final = (write == len); // is this the last block?
|
final = (write == len); // is this the last block?
|
||||||
|
chunks = write / RAW_CHUNK;
|
||||||
|
leftovers = write % RAW_CHUNK;
|
||||||
|
|
||||||
if (flag != 0) {
|
if (flag != 0) {
|
||||||
*dest = flag;
|
*dest = flag;
|
||||||
@ -49,43 +135,91 @@ encode_data(char *buf, int len, int space, char *dest, char flag)
|
|||||||
}
|
}
|
||||||
dest++;
|
dest++;
|
||||||
|
|
||||||
|
bzero(encoded, sizeof(encoded));
|
||||||
|
ep = encoded;
|
||||||
|
dp = buf;
|
||||||
|
for (i = 0; i < chunks; i++) {
|
||||||
|
encode_chunk(ep, dp);
|
||||||
|
ep += ENC_CHUNK;
|
||||||
|
dp += RAW_CHUNK;
|
||||||
|
}
|
||||||
|
realwrite = ENC_CHUNK * chunks;
|
||||||
|
bzero(padding, sizeof(padding));
|
||||||
|
pp = padding;
|
||||||
|
if (leftovers) {
|
||||||
|
pp += RAW_CHUNK - leftovers;
|
||||||
|
memcpy(pp, dp, leftovers);
|
||||||
|
|
||||||
|
pp = padding;
|
||||||
|
*ep++ = padder[leftovers];
|
||||||
|
encode_chunk(ep, pp);
|
||||||
|
|
||||||
|
realwrite += ENC_CHUNK + 1; // plus padding character
|
||||||
|
}
|
||||||
|
ep = encoded;
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
for (i = 0; i < write; i++) {
|
for (i = 1; i <= realwrite; i++) {
|
||||||
if (i > 0 && i % CHUNK == 0) {
|
if (i % SPACING == 0) {
|
||||||
*dest = '.';
|
*dest++ = '.';
|
||||||
dest++;
|
|
||||||
}
|
}
|
||||||
t = (buf[i] & 0xF0) >> 4;
|
*dest++ = *ep++;
|
||||||
*dest++ = to_hex[t];
|
|
||||||
t = buf[i] & 0x0F;
|
|
||||||
*dest++ = to_hex[t];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return write;
|
return write;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
decode_data(char *dest, int size, const char *src, char *srcend)
|
decode_data(char *dest, int size, const char *src, char *srcend)
|
||||||
{
|
{
|
||||||
int r;
|
|
||||||
int len;
|
int len;
|
||||||
|
int i;
|
||||||
|
int chunks;
|
||||||
|
int padded;
|
||||||
|
char encoded[255];
|
||||||
|
char padding[5];
|
||||||
|
char *pp;
|
||||||
|
char *ep;
|
||||||
|
|
||||||
|
// Copy flag
|
||||||
len = 1;
|
len = 1;
|
||||||
*dest = *src;
|
*dest = *src;
|
||||||
dest++;
|
dest++;
|
||||||
src++;
|
src++;
|
||||||
|
|
||||||
|
bzero(encoded, sizeof(encoded));
|
||||||
|
ep = encoded;
|
||||||
while(len < size && src < srcend) {
|
while(len < size && src < srcend) {
|
||||||
if(*src == '.') {
|
if(*src == '.') {
|
||||||
src++;
|
src++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sscanf(src, "%02X", &r);
|
*ep++ = *src++;
|
||||||
*dest++ = (char)r;
|
|
||||||
src+=2;
|
|
||||||
len++;
|
|
||||||
}
|
}
|
||||||
|
chunks = strlen(encoded) / 8;
|
||||||
|
padded = strlen(encoded) % 8;
|
||||||
|
|
||||||
|
ep = encoded;
|
||||||
|
for (i = 0; i < chunks-1; i++) {
|
||||||
|
decode_chunk(dest, ep);
|
||||||
|
dest += RAW_CHUNK;
|
||||||
|
ep += ENC_CHUNK;
|
||||||
|
len += RAW_CHUNK;
|
||||||
|
}
|
||||||
|
// Read last chunk:
|
||||||
|
if (padded) {
|
||||||
|
pp = padding;
|
||||||
|
padded = *ep++ - '0';
|
||||||
|
decode_chunk(pp, ep);
|
||||||
|
pp += RAW_CHUNK - padded;
|
||||||
|
memcpy(dest, pp, padded);
|
||||||
|
len += padded;
|
||||||
|
} else {
|
||||||
|
decode_chunk(dest, ep);
|
||||||
|
len += RAW_CHUNK;
|
||||||
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user