/* base64.c -- Encode/decode integers in base64 format * Created: Mon Sep 23 16:55:12 1996 by faith@dict.org * Revised: Sat Mar 30 12:02:36 2002 by faith@dict.org * Copyright 1996, 2002 Rickard E. Faith (faith@dict.org) * Copyright 2008 Casey Marshall. * * The original license for this library was the GNU Library General * Public License, version 2, or any later version. In accordance with * section 3 of the LGPL, as a part of Arrow this file is licensed * under the GNU General Public License, version 3. The notice for the * new license terms follow: * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 . * * $Id: base64.c,v 1.5 2002/08/02 19:43:15 faith Exp $ * * \section{Base-64 Routines} * * \intro These routines use the 64-character subset of International * Alphabet IA5 discussed in RFC 1421 (printeable encoding) and RFC 1522 * (base64 MIME). * Value Encoding Value Encoding Value Encoding Value Encoding 0 A 17 R 34 ) 51 } 1 B 18 S 35 , 52 0 2 C 19 T 36 - 53 1 3 D 20 U 37 : 54 2 4 E 21 V 38 ; 55 3 5 F 22 W 39 < 56 4 6 G 23 X 40 > 57 5 7 H 24 Y 41 ? 58 6 8 I 25 Z 42 @ 59 7 9 J 26 ! 43 [ 60 8 10 K 27 " 44 ~ 61 9 11 L 28 # 45 ] 62 + 12 M 29 $ 46 ^ 63 * 13 N 30 % 47 _ 14 O 31 & 48 ` (pad) = 15 P 32 ' 49 { 16 Q 33 ( 50 | * */ /* * Summary of changes by Casey Marshall for arrow: * * - extend idea to 64-bit values. * - only use characters that can be parts of a file name on * case-insensitive file systems. */ #include #include static unsigned char b64_list[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'(),-:;<>?@[~]^_`{|}0123456789+*"; #define XX 100 static int b64_index[256] = { XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,26,27,28, 29,30,31,32, 33,34,63,62, 35,36,XX,XX, 52,53,54,55, 56,57,58,59, 60,61,37,38, 39,XX,40,41, 42, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, 15,16,17,18, 19,20,21,22, 23,24,25,43, XX,45,46,47, 48,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,49, 50,51,44,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, }; /* |b64_encode| encodes |val| in a printable base 64 format. A MSB-first encoding is generated. */ void b64_encode (uint64_t val, char *result) { char *c; int i; result[ 0] = b64_list[ (val & 0xf000000000000000ULL) >> 60 ]; result[ 1] = b64_list[ (val & 0x0fc0000000000000ULL) >> 54 ]; result[ 2] = b64_list[ (val & 0x003f000000000000ULL) >> 48 ]; result[ 3] = b64_list[ (val & 0x0000fc0000000000ULL) >> 42 ]; result[ 4] = b64_list[ (val & 0x000003f000000000ULL) >> 36 ]; result[ 5] = b64_list[ (val & 0x0000000fc0000000ULL) >> 30 ]; result[ 6] = b64_list[ (val & 0x000000003f000000ULL) >> 24 ]; result[ 7] = b64_list[ (val & 0x0000000000fc0000ULL) >> 18 ]; result[ 8] = b64_list[ (val & 0x000000000003f000ULL) >> 12 ]; result[ 9] = b64_list[ (val & 0x0000000000000fc0ULL) >> 6 ]; result[10] = b64_list[ (val & 0x000000000000003fULL) ]; result[11] = 0; c = result + 10; for (i = 0; i < 10; i++) { if (result[i] != b64_list[0]) { c = result + i; break; } } memmove (result, c, strlen(c) + 1); } int b64_decode (const char *val, uint64_t *out) { uint64_t v = 0; int i; int offset = 0; int len = strlen (val); for (i = len - 1; i >= 0; i--) { uint64_t tmp = b64_index[(unsigned char) val[i]]; if (tmp == XX) return -1; v |= tmp << offset; offset += 6; } *out = v; return 0; }