From 784c86611d3194a10ccc24cf11fe7da606387ad5 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 20 Sep 2014 22:23:53 +0100 Subject: [PATCH] Add base32 encoding utility. --- src/libutil/util.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++ src/libutil/util.h | 8 ++++++ 2 files changed, 72 insertions(+) diff --git a/src/libutil/util.c b/src/libutil/util.c index f06b7a62d..a4117d3c3 100644 --- a/src/libutil/util.c +++ b/src/libutil/util.c @@ -2246,3 +2246,67 @@ rspamd_inet_address_connect (rspamd_inet_addr_t *addr, gint type, return fd; } + +/* + * We use here z-base32 encoding described here: + * http://philzimmermann.com/docs/human-oriented-base-32-encoding.txt + */ + +gchar * +rspamd_encode_base32(guchar *in, gsize inlen) +{ + gint remain = -1, r, x; + gsize i; + gsize outlen = inlen * 8 / 5 + 1; + gchar *out; + static const char b32[]="ybndrfg8ejkmcpqxot1uwisza345h769"; + + out = g_malloc (outlen); + for (i = 0, r = 0; i < inlen; i++) { + switch (i % 5) { + case 0: + /* 8 bits of input and 3 to remain */ + x = in[i]; + remain = in[i] >> 5; + out[r++] = b32[x & 0x1F]; + break; + case 1: + /* 11 bits of input, 1 to remain */ + x = remain | in[i] << 3; + out[r++] = b32[x & 0x1F]; + out[r++] = b32[x >> 5 & 0x1F]; + remain = x >> 10; + break; + case 2: + /* 9 bits of input, 4 to remain */ + x = remain | in[i] << 1; + out[r++] = b32[x & 0x1F]; + remain = x >> 5; + break; + case 3: + /* 12 bits of input, 2 to remain */ + x = remain | in[i] << 4; + out[r++] = b32[x & 0x1F]; + out[r++] = b32[x >> 5 & 0x1F]; + remain = x >> 10 & 0x3; + break; + case 4: + /* 10 bits of output, nothing to remain */ + x = remain | in[i] << 2; + out[r++] = b32[x & 0x1F]; + out[r++] = b32[x >> 5 & 0x1F]; + remain = -1; + break; + default: + /* Not to be happen */ + break; + } + + } + if (remain >= 0) + out[r++] = b32[remain]; + + out[r] = 0; + + return out; +} diff --git a/src/libutil/util.h b/src/libutil/util.h index 3a44cb1d8..e2e20da62 100644 --- a/src/libutil/util.h +++ b/src/libutil/util.h @@ -489,4 +489,12 @@ void rspamd_inet_address_set_port (rspamd_inet_addr_t *addr, uint16_t port); int rspamd_inet_address_connect (rspamd_inet_addr_t *addr, gint type, gboolean async); +/** + * Encode string using base32 encoding + * @param in input + * @param inlen input length + * @return freshly allocated base32 encoding of a specified string + */ +gchar * rspamd_encode_base32(guchar *in, gsize inlen); + #endif -- 2.39.5