base64.c (3415B)
1 /* base64.h 2 * 3 * Copyright 2011 Brian Swetland <swetland@frotz.net> 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <stdint.h> 21 #include <unistd.h> 22 #include <string.h> 23 24 typedef uint8_t u8; 25 typedef uint32_t u32; 26 27 #define OP_MASK 0xC0 28 #define OP_BITS 0x00 29 #define OP_END 0x40 30 #define OP_SKIP 0x80 31 #define OP_BAD 0xC0 32 33 static u8 DTABLE[256] = 34 "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x80\x80\xc0\xc0\x80\xc0\xc0" 35 "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0" 36 "\x80\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x3e\xc0\xc0\xc0\x3f" 37 "\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\xc0\xc0\xc0\x40\xc0\xc0" 38 "\xc0\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e" 39 "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\xc0\xc0\xc0\xc0\xc0" 40 "\xc0\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28" 41 "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\xc0\xc0\xc0\xc0\xc0" 42 "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0" 43 "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0" 44 "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0" 45 "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0" 46 "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0" 47 "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0" 48 "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0" 49 "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0"; 50 51 static u8 ETABLE[64] = 52 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 53 "abcdefghijklmnopqrstuvwxyz" 54 "0123456789+/"; 55 56 int base64_decode(u8 *data, u32 len, u8 *out) 57 { 58 u8 *start = out; 59 u32 tmp = 0, pos = 0; 60 61 while (len-- > 0) { 62 u8 x = DTABLE[*data++]; 63 switch (x & OP_MASK) { 64 case OP_BITS: 65 tmp = (tmp << 6) | x; 66 if (++pos == 4) { 67 *out++ = tmp >> 16; 68 *out++ = tmp >> 8; 69 *out++ = tmp; 70 tmp = 0; 71 pos = 0; 72 } 73 break; 74 case OP_SKIP: 75 break; 76 case OP_END: 77 if (pos == 2) { 78 if (*data != '=') 79 return -1; 80 *out++ = (tmp >> 4); 81 } else if (pos == 3) { 82 *out++ = (tmp >> 10); 83 *out++ = (tmp >> 2); 84 } else { 85 return -1; 86 } 87 return out - start; 88 case OP_BAD: 89 return -1; 90 } 91 } 92 93 if (pos != 0) 94 return -1; 95 96 return out - start; 97 } 98 99 int base64_encode(u8 *data, u32 len, u8 *out) 100 { 101 u8 *start = out; 102 u32 n; 103 104 while (len >= 3) { 105 n = (data[0] << 16) | (data[1] << 8) | data[2]; 106 data += 3; 107 len -= 3; 108 *out++ = ETABLE[(n >> 18) & 63]; 109 *out++ = ETABLE[(n >> 12) & 63]; 110 *out++ = ETABLE[(n >> 6) & 63]; 111 *out++ = ETABLE[n & 63]; 112 } 113 if (len == 2) { 114 *out++ = ETABLE[(data[0] >> 2) & 63]; 115 *out++ = ETABLE[((data[0] << 4) | (data[1] >> 4)) & 63]; 116 *out++ = ETABLE[(data[1] << 2) & 63]; 117 *out++ = '='; 118 } else if (len == 1) { 119 *out++ = ETABLE[(data[0] >> 2) & 63]; 120 *out++ = ETABLE[(data[0] << 4) & 63]; 121 *out++ = '='; 122 *out++ = '='; 123 } 124 125 return out - start; 126 }