summaryrefslogtreecommitdiffabout
path: root/pwmanager/pwmanager/base64.cpp
Unidiff
Diffstat (limited to 'pwmanager/pwmanager/base64.cpp') (more/less context) (show whitespace changes)
-rw-r--r--pwmanager/pwmanager/base64.cpp207
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
48static const char prtcode[] =
49 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
50
51
52string 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
65string 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
78void Base64::initCtx()
79{
80 ctx.temp = 0;
81 ctx.bytes = 0;
82 ctx.buf = "";
83}
84
85void 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
103void Base64::decFinalizeCtx()
104{
105 if (ctx.bytes == 1)
106 decodeChar('A');
107}
108
109void 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
136void 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
183bool 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}