/* zb32.c - z-base-32 functions * Copyright (C) 2014 Werner Koch * * This file is part of GnuPG. * * This file is free software; you can redistribute it and/or modify * it under the terms of either * * - the GNU Lesser General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at * your option) any later version. * * or * * - the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at * your option) any later version. * * or both in parallel, as here. * * This file is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #include #include #include #include #include #include #include "util.h" #include "zb32.h" /* Zooko's base32 variant. See RFC-6189 and http://philzimmermann.com/docs/human-oriented-base-32-encoding.txt Caller must xfree the returned string. Returns NULL and sets ERRNO on error. To avoid integer overflow DATALEN is limited to 2^16 bytes. Note, that DATABITS is measured in bits!. */ char * zb32_encode (const void *data, unsigned int databits) { static char const zb32asc[32] = {'y','b','n','d','r','f','g','8', 'e','j','k','m','c','p','q','x', 'o','t','1','u','w','i','s','z', 'a','3','4','5','h','7','6','9' }; const unsigned char *s; char *output, *d; size_t datalen; datalen = (databits + 7) / 8; if (datalen > (1 << 16)) { errno = EINVAL; return NULL; } d = output = xtrymalloc (8 * (datalen / 5) + 2 * (datalen % 5) - ((datalen%5)>2) + 1); if (!output) return NULL; /* I use straightforward code. The compiler should be able to do a better job on optimization than me and it is easier to read. */ for (s = data; datalen >= 5; s += 5, datalen -= 5) { *d++ = zb32asc[((s[0] ) >> 3) ]; *d++ = zb32asc[((s[0] & 7) << 2) | (s[1] >> 6) ]; *d++ = zb32asc[((s[1] & 63) >> 1) ]; *d++ = zb32asc[((s[1] & 1) << 4) | (s[2] >> 4) ]; *d++ = zb32asc[((s[2] & 15) << 1) | (s[3] >> 7) ]; *d++ = zb32asc[((s[3] & 127) >> 2) ]; *d++ = zb32asc[((s[3] & 3) << 3) | (s[4] >> 5) ]; *d++ = zb32asc[((s[4] & 31) ) ]; } switch (datalen) { case 4: *d++ = zb32asc[((s[0] ) >> 3) ]; *d++ = zb32asc[((s[0] & 7) << 2) | (s[1] >> 6) ]; *d++ = zb32asc[((s[1] & 63) >> 1) ]; *d++ = zb32asc[((s[1] & 1) << 4) | (s[2] >> 4) ]; *d++ = zb32asc[((s[2] & 15) << 1) | (s[3] >> 7) ]; *d++ = zb32asc[((s[3] & 127) >> 2) ]; *d++ = zb32asc[((s[3] & 3) << 3) ]; break; case 3: *d++ = zb32asc[((s[0] ) >> 3) ]; *d++ = zb32asc[((s[0] & 7) << 2) | (s[1] >> 6) ]; *d++ = zb32asc[((s[1] & 63) >> 1) ]; *d++ = zb32asc[((s[1] & 1) << 4) | (s[2] >> 4) ]; *d++ = zb32asc[((s[2] & 15) << 1) ]; break; case 2: *d++ = zb32asc[((s[0] ) >> 3) ]; *d++ = zb32asc[((s[0] & 7) << 2) | (s[1] >> 6) ]; *d++ = zb32asc[((s[1] & 63) >> 1) ]; *d++ = zb32asc[((s[1] & 1) << 4) ]; break; case 1: *d++ = zb32asc[((s[0] ) >> 3) ]; *d++ = zb32asc[((s[0] & 7) << 2) ]; break; default: break; } *d = 0; /* Need to strip some bytes if not a multiple of 40. */ output[(databits + 5 - 1) / 5] = 0; return output; }