aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llbase32.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llcommon/llbase32.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llbase32.cpp b/linden/indra/llcommon/llbase32.cpp
new file mode 100644
index 0000000..711ba63
--- /dev/null
+++ b/linden/indra/llcommon/llbase32.cpp
@@ -0,0 +1,214 @@
1/**
2 * @file llbase32.cpp
3 * @brief base32 encoding that returns a std::string
4 * @author James Cook
5 *
6 * Based on code from bitter
7 * http://ghostwhitecrab.com/bitter/
8 *
9 * Copyright (c) 2006 Christian Biere <christianbiere@gmx.de>
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the authors nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38#include "linden_common.h"
39
40#include "llbase32.h"
41
42#include <string>
43
44// bitter - base32.c starts here
45
46/*
47 * See RFC 3548 for details about Base 32 encoding:
48 * http://www.faqs.org/rfcs/rfc3548.html
49 */
50
51static const char base32_alphabet[32] = {
52 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
53 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
54 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
55 'Y', 'Z', '2', '3', '4', '5', '6', '7'
56};
57
58size_t
59base32_encode(char *dst, size_t size, const void *data, size_t len)
60{
61 size_t i = 0;
62 const U8 *p = (const U8*)data;
63 const char *end = &dst[size];
64 char *q = dst;
65
66 do {
67 size_t j, k;
68 U8 x[5];
69 char s[8];
70
71 switch (len - i) {
72 case 4: k = 7; break;
73 case 3: k = 5; break;
74 case 2: k = 3; break;
75 case 1: k = 2; break;
76 default:
77 k = 8;
78 }
79
80 for (j = 0; j < 5; j++)
81 x[j] = i < len ? p[i++] : 0;
82
83/*
84 +-------+-----------+--------+
85 | target| source | source |
86 | byte | bits | byte |
87 +-------+-----------+--------+
88 | 0 | 7 6 5 4 3 | 0 |
89 | 1 | 2 1 0 7 6 | 0-1 |
90 | 2 | 5 4 3 2 1 | 1 |
91 | 3 | 0 7 6 5 4 | 1-2 |
92 | 4 | 3 2 1 0 7 | 2-3 |
93 | 5 | 6 5 4 3 2 | 3 |
94 | 6 | 1 0 7 6 5 | 3-4 |
95 | 7 | 4 3 2 1 0 | 4 |
96 +-------+-----------+--------+
97
98*/
99
100 s[0] = (x[0] >> 3);
101 s[1] = ((x[0] & 0x07) << 2) | (x[1] >> 6);
102 s[2] = (x[1] >> 1) & 0x1f;
103 s[3] = ((x[1] & 0x01) << 4) | (x[2] >> 4);
104 s[4] = ((x[2] & 0x0f) << 1) | (x[3] >> 7);
105 s[5] = (x[3] >> 2) & 0x1f;
106 s[6] = ((x[3] & 0x03) << 3) | (x[4] >> 5);
107 s[7] = x[4] & 0x1f;
108
109 for (j = 0; j < k && q != end; j++)
110 *q++ = base32_alphabet[(U8) s[j]];
111
112 } while (i < len);
113
114 return q - dst;
115}
116
117/* *TODO: Implement base32 encode.
118
119#define ARRAY_LEN(a) (sizeof (a) / sizeof((a)[0]))
120
121static inline int
122ascii_toupper(int c)
123{
124 return c >= 97 && c <= 122 ? c - 32 : c;
125}
126
127static inline int
128ascii_tolower(int c)
129{
130 return c >= 65 && c <= 90 ? c + 32 : c;
131}
132
133
134static char base32_map[(unsigned char) -1];
135
136size_t
137base32_decode(char *dst, size_t size, const void *data, size_t len)
138{
139 const char *end = &dst[size];
140 const unsigned char *p = data;
141 char *q = dst;
142 size_t i;
143 unsigned max_pad = 3;
144
145 if (0 == base32_map[0]) {
146 for (i = 0; i < ARRAY_LEN(base32_map); i++) {
147 const char *x;
148
149 x = memchr(base32_alphabet, ascii_toupper(i), sizeof base32_alphabet);
150 base32_map[i] = x ? (x - base32_alphabet) : (unsigned char) -1;
151 }
152 }
153
154 for (i = 0; i < len && max_pad > 0; i++) {
155 unsigned char c;
156 char s[8];
157 size_t j;
158
159 c = p[i];
160 if ('=' == c) {
161 max_pad--;
162 c = 0;
163 } else {
164 c = base32_map[c];
165 if ((unsigned char) -1 == c) {
166 return -1;
167 }
168 }
169
170 j = i % ARRAY_LEN(s);
171 s[j] = c;
172
173 if (7 == j) {
174 char b[5];
175
176 b[0] = ((s[0] << 3) & 0xf8) | ((s[1] >> 2) & 0x07);
177 b[1] = ((s[1] & 0x03) << 6) | ((s[2] & 0x1f) << 1) | ((s[3] >> 4) & 1);
178 b[2] = ((s[3] & 0x0f) << 4) | ((s[4] >> 1) & 0x0f);
179 b[3] = ((s[4] & 1) << 7) | ((s[5] & 0x1f) << 2) | ((s[6] >> 3) & 0x03);
180 b[4] = ((s[6] & 0x07) << 5) | (s[7] & 0x1f);
181
182 for (j = 0; j < ARRAY_LEN(b); j++) {
183 if (q != end)
184 *q = b[j];
185 q++;
186 }
187 }
188 }
189
190 return q - dst;
191}
192*/
193
194
195// static
196std::string LLBase32::encode(const U8* input, size_t input_size)
197{
198 std::string output;
199 if (input)
200 {
201 // Each 5 byte chunk of input is represented by an
202 // 8 byte chunk of output.
203 size_t input_chunks = (input_size + 4) / 5;
204 size_t output_size = input_chunks * 8;
205
206 output.resize(output_size);
207
208 size_t encoded = base32_encode(&output[0], output_size, input, input_size);
209
210 llinfos << "encoded " << encoded << " into buffer of size " << output_size
211 << llendl;
212 }
213 return output;
214}