Diffstat (limited to 'pwmanager/pwmanager/base64.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | pwmanager/pwmanager/base64.cpp | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/pwmanager/pwmanager/base64.cpp b/pwmanager/pwmanager/base64.cpp new file mode 100644 index 0000000..0360678 --- a/dev/null +++ b/pwmanager/pwmanager/base64.cpp | |||
@@ -0,0 +1,207 @@ | |||
1 | /******************************************************************* | ||
2 | * base64.h | ||
3 | * © Copyright 1995 John Halleck | ||
4 | * All Rights Reserved | ||
5 | * | ||
6 | * ported to c++ by Michael Buesch <mbuesch@freenet.de> | ||
7 | * | ||
8 | * --ABSTRACT-- base64.h | ||
9 | * Do the base 64 encoding as used by PEM and MIME. | ||
10 | * | ||
11 | * --KEYWORDS-- base64.h | ||
12 | * | ||
13 | * --CONTENTS-- base64.h | ||
14 | * Date, Department, Author | ||
15 | * 23nov1994, John Halleck | ||
16 | * Revision history | ||
17 | * For each revision: Date, change summary, authorizing document, | ||
18 | * change department, section, author | ||
19 | * 23nov1994, Initial Creation, John Halleck | ||
20 | * 8apr1995, split library into hex and base64 libraries, John Halleck | ||
21 | * Unit purpose | ||
22 | * (What does this do?) | ||
23 | * [Nothing] | ||
24 | * External Units accessed | ||
25 | * Name, purpose, access summary | ||
26 | * [None] | ||
27 | * Exceptions propagated by this unit | ||
28 | * [None] | ||
29 | * Machine-dependencies | ||
30 | * Access type, purpose, and justification | ||
31 | * [None] | ||
32 | * Compiler-dependencies | ||
33 | * [None] | ||
34 | *********************************************************************/ | ||
35 | |||
36 | /*************************************************************************** | ||
37 | * * | ||
38 | * This program is free software; you can redistribute it and/or modify * | ||
39 | * it under the terms of the GNU General Public License version 2 * | ||
40 | * as published by the Free Software Foundation. * | ||
41 | * * | ||
42 | ***************************************************************************/ | ||
43 | |||
44 | #include "base64.h" | ||
45 | #include "globalstuff.h" | ||
46 | |||
47 | |||
48 | static const char prtcode[] = | ||
49 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
50 | |||
51 | |||
52 | string Base64::encode(const string &data) | ||
53 | { | ||
54 | initCtx(); | ||
55 | string::const_iterator i = data.begin(), | ||
56 | end = data.end(); | ||
57 | while (i != end) { | ||
58 | encodeChar(*i); | ||
59 | ++i; | ||
60 | } | ||
61 | encFinalizeCtx(); | ||
62 | return ctx.buf; | ||
63 | } | ||
64 | |||
65 | string Base64::decode(const string &data) | ||
66 | { | ||
67 | initCtx(); | ||
68 | string::const_iterator i = data.begin(), | ||
69 | end = data.end(); | ||
70 | while (i != end) { | ||
71 | decodeChar(*i); | ||
72 | ++i; | ||
73 | } | ||
74 | decFinalizeCtx(); | ||
75 | return ctx.buf; | ||
76 | } | ||
77 | |||
78 | void Base64::initCtx() | ||
79 | { | ||
80 | ctx.temp = 0; | ||
81 | ctx.bytes = 0; | ||
82 | ctx.buf = ""; | ||
83 | } | ||
84 | |||
85 | void Base64::encFinalizeCtx() | ||
86 | { | ||
87 | /* flush the output side of things, by putting out the last characters */ | ||
88 | switch (ctx.bytes) { | ||
89 | case 0: | ||
90 | /* nothing in progress */ | ||
91 | break; | ||
92 | case 2: | ||
93 | ctx.buf.append(1, static_cast<char>(prtcode[ctx.temp << 2 & 0x3F])); | ||
94 | ctx.buf.append(1, '='); | ||
95 | break; | ||
96 | case 1: | ||
97 | ctx.buf.append(1, static_cast<char>(prtcode[ctx.temp << 4 & 0x3F])); | ||
98 | ctx.buf.append(1, '='); | ||
99 | ctx.buf.append(1, '='); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | void Base64::decFinalizeCtx() | ||
104 | { | ||
105 | if (ctx.bytes == 1) | ||
106 | decodeChar('A'); | ||
107 | } | ||
108 | |||
109 | void Base64::encodeChar(unsigned char c) | ||
110 | { | ||
111 | int result; | ||
112 | |||
113 | /* Add this 8 bit byte to what we have...*/ | ||
114 | result = ctx.temp; | ||
115 | result = (result << 8) | (c & 0xFF); | ||
116 | |||
117 | /* And output all 6 bit base 64 characters now formed */ | ||
118 | switch (ctx.bytes++) { | ||
119 | case 0: | ||
120 | ctx.buf.append(1, static_cast<char>(prtcode[result >> 2 & 0x3F])); | ||
121 | result &= 0x3; | ||
122 | break; | ||
123 | case 1: | ||
124 | ctx.buf.append(1, static_cast<char>(prtcode[result >> 4 & 0x3F])); | ||
125 | result &= 0xF; | ||
126 | break; | ||
127 | case 2: | ||
128 | ctx.buf.append(1, static_cast<char>(prtcode[result >> 6 & 0x3F])); | ||
129 | ctx.buf.append(1, static_cast<char>(prtcode[result & 0x3F])); | ||
130 | result = 0; | ||
131 | ctx.bytes = 0; | ||
132 | } | ||
133 | ctx.temp = result; | ||
134 | } | ||
135 | |||
136 | void Base64::decodeChar(char c) | ||
137 | { | ||
138 | int result; | ||
139 | |||
140 | result = ctx.temp; | ||
141 | |||
142 | /* Convert Base64 character to its 6 bit nibble */ | ||
143 | if (c == '/') { | ||
144 | result = (result << 6) | 63; | ||
145 | } else if (c == '+') { | ||
146 | result = (result << 6) | 62; | ||
147 | } else if (c >= 'A' && c <= 'Z') { | ||
148 | result = (result << 6) | (c - 'A'); | ||
149 | } else if (c >= 'a' && c <= 'z') { | ||
150 | result = (result << 6) | (c - 'a' + 26); | ||
151 | } else if (c >= '0' && c <= '9') { | ||
152 | result = (result << 6) | (c - '0' + 52); | ||
153 | } else if (c == '=') { | ||
154 | ctx.bytes = 0; | ||
155 | ctx.temp = 0; | ||
156 | } | ||
157 | |||
158 | /* Add that nibble to the output, outputting any complete 8 bit bytes formed */ | ||
159 | switch (ctx.bytes++) { | ||
160 | case 0: | ||
161 | break; | ||
162 | case 1: | ||
163 | ctx.buf.append(1, static_cast<char>(result >> 4 & 0xFF)); | ||
164 | result &= 0xF; | ||
165 | break; | ||
166 | case 2: | ||
167 | ctx.buf.append(1, static_cast<char>(result >> 2 & 0xFF)); | ||
168 | result &= 0x3; | ||
169 | break; | ||
170 | case 3: | ||
171 | ctx.buf.append(1, static_cast<char>(result & 0xFF)); | ||
172 | ctx.bytes = 0; | ||
173 | result = 0; | ||
174 | } | ||
175 | if (c == '=') { | ||
176 | ctx.bytes = 0; | ||
177 | result = 0; | ||
178 | } | ||
179 | |||
180 | ctx.temp = result; | ||
181 | } | ||
182 | |||
183 | bool Base64::selfTest() | ||
184 | { | ||
185 | string plain1("Base64"); | ||
186 | string plain2("abcdefghijklmnopqrstuvwxyz"); | ||
187 | string enc1("QmFzZTY0"); | ||
188 | string enc2("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="); | ||
189 | string buf; | ||
190 | |||
191 | Base64 base64; | ||
192 | |||
193 | buf = base64.encode(plain1); | ||
194 | if (unlikely(buf != enc1)) | ||
195 | return false; | ||
196 | buf = base64.decode(buf); | ||
197 | if (unlikely(buf != plain1)) | ||
198 | return false; | ||
199 | |||
200 | buf = base64.encode(plain2); | ||
201 | if (unlikely(buf != enc2)) | ||
202 | return false; | ||
203 | buf = base64.decode(buf); | ||
204 | if (unlikely(buf != plain2)) | ||
205 | return false; | ||
206 | return true; | ||
207 | } | ||