Mana
Loading...
Searching...
No Matches
base64.cpp
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | PHP HTML Embedded Scripting Language Version 3.0 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2000 PHP Development Team (See Credits file) |
6 +----------------------------------------------------------------------+
7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of one of the following licenses: |
9 | |
10 | A) the GNU General Public License as published by the Free Software |
11 | Foundation; either version 2 of the License, or (at your option) |
12 | any later version. |
13 | |
14 | B) the PHP License as published by the PHP Development Team and |
15 | included in the distribution in the file: LICENSE |
16 | |
17 | This program is distributed in the hope that it will be useful, |
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | GNU General Public License for more details. |
21 | |
22 | You should have received a copy of both licenses referred to here. |
23 | If you did not, or have any questions about PHP licensing, please |
24 | contact core@php.net. |
25 +----------------------------------------------------------------------+
26 | Author: Jim Winstead (jimw@php.net) |
27 +----------------------------------------------------------------------+
28 */
29
30#include "utils/base64.h"
31
32#include <cstdlib>
33#include <cstring>
34
35static char base64_table[] =
36{
37 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
38 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
39 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
40 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
41 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
42};
43static char base64_pad = '=';
44
45unsigned char *php3_base64_encode(const unsigned char *string, int length, int *ret_length)
46{
47 const unsigned char *current = string;
48 int i = 0;
49 auto *result = (unsigned char *)malloc(((length + 3 - length % 3) * 4 / 3 + 1) * sizeof(char));
50
51 while (length > 2)
52 { /* keep going until we have less than 24 bits */
53 result[i++] = base64_table[current[0] >> 2];
54 result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
55 result[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
56 result[i++] = base64_table[current[2] & 0x3f];
57
58 current += 3;
59 length -= 3; /* we just handle 3 octets of data */
60 }
61
62 /* now deal with the tail end of things */
63 if (length != 0)
64 {
65 result[i++] = base64_table[current[0] >> 2];
66 if (length > 1)
67 {
68 result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
69 result[i++] = base64_table[(current[1] & 0x0f) << 2];
70 result[i++] = base64_pad;
71 }
72 else
73 {
74 result[i++] = base64_table[(current[0] & 0x03) << 4];
75 result[i++] = base64_pad;
76 result[i++] = base64_pad;
77 }
78 }
79 if (ret_length)
80 {
81 *ret_length = i;
82 }
83 result[i] = '\0';
84 return result;
85}
86
87/* as above, but backwards. :) */
88unsigned char *php3_base64_decode(const unsigned char *string, int length, int *ret_length)
89{
90 const unsigned char *current = string;
91 int ch, i = 0, j = 0, k;
92 char *chp;
93
94 auto *result = (unsigned char *)malloc(length + 1);
95
96 if (result == nullptr)
97 {
98 return nullptr;
99 }
100
101 /* run through the whole string, converting as we go */
102 while ((ch = *current++) != '\0')
103 {
104 if (ch == base64_pad) break;
105
106 /* When Base64 gets POSTed, all pluses are interpreted as spaces.
107 This line changes them back. It's not exactly the Base64 spec,
108 but it is completely compatible with it (the spec says that
109 spaces are invalid). This will also save many people considerable
110 headache. - Turadg Aleahmad <turadg@wise.berkeley.edu>
111 */
112
113 if (ch == ' ') ch = '+';
114
115 chp = strchr(base64_table, ch);
116 if (chp == nullptr) continue;
117 ch = chp - base64_table;
118
119 switch(i % 4)
120 {
121 case 0:
122 result[j] = ch << 2;
123 break;
124 case 1:
125 result[j++] |= ch >> 4;
126 result[j] = (ch & 0x0f) << 4;
127 break;
128 case 2:
129 result[j++] |= ch >>2;
130 result[j] = (ch & 0x03) << 6;
131 break;
132 case 3:
133 result[j++] |= ch;
134 break;
135 }
136 i++;
137 }
138
139 k = j;
140 /* mop things up if we ended on a boundary */
141 if (ch == base64_pad)
142 {
143 switch(i % 4)
144 {
145 case 0:
146 case 1:
147 free(result);
148 return nullptr;
149 case 2:
150 k++;
151 case 3:
152 result[k++] = 0;
153 }
154 }
155 if (ret_length)
156 {
157 *ret_length = j;
158 }
159 result[k] = '\0';
160 return result;
161}
unsigned char * php3_base64_encode(const unsigned char *string, int length, int *ret_length)
Definition base64.cpp:45
unsigned char * php3_base64_decode(const unsigned char *string, int length, int *ret_length)
Definition base64.cpp:88