]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/util/base64.c
4 * Copyright(c) Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk/stdinc.h"
35 #include "spdk/endian.h"
36 #include "spdk/base64.h"
38 #define BASE64_ENC_BITMASK 0x3FUL
39 #define BASE64_PADDING_CHAR '='
41 static const char base64_enc_table
[] =
42 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
43 "abcdefghijklmnopqrstuvwxyz"
46 static const char base64_urfsafe_enc_table
[] =
47 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
48 "abcdefghijklmnopqrstuvwxyz"
52 base64_dec_table
[] = {
53 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
54 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
55 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
56 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 255, 255, 255,
57 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
58 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
59 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
60 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
61 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
62 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
63 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
64 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
65 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
66 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
67 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
68 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
72 base64_urlsafe_dec_table
[] = {
73 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
74 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
75 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255,
76 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 255, 255, 255,
77 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
78 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63,
79 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
80 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
81 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
82 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
83 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
84 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
85 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
86 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
87 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
88 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
92 _spdk_base64_encode(char *dst
, const char *enc_table
, const void *src
, size_t src_len
)
96 if (!dst
|| !src
|| src_len
<= 0) {
100 while (src_len
>= 4) {
101 raw_u32
= from_be32(src
);
103 *dst
++ = enc_table
[(raw_u32
>> 26) & BASE64_ENC_BITMASK
];
104 *dst
++ = enc_table
[(raw_u32
>> 20) & BASE64_ENC_BITMASK
];
105 *dst
++ = enc_table
[(raw_u32
>> 14) & BASE64_ENC_BITMASK
];
106 *dst
++ = enc_table
[(raw_u32
>> 8) & BASE64_ENC_BITMASK
];
117 memcpy(&raw_u32
, src
, src_len
);
118 raw_u32
= from_be32(&raw_u32
);
120 *dst
++ = enc_table
[(raw_u32
>> 26) & BASE64_ENC_BITMASK
];
121 *dst
++ = enc_table
[(raw_u32
>> 20) & BASE64_ENC_BITMASK
];
122 *dst
++ = (src_len
>= 2) ? enc_table
[(raw_u32
>> 14) & BASE64_ENC_BITMASK
] : BASE64_PADDING_CHAR
;
123 *dst
++ = (src_len
== 3) ? enc_table
[(raw_u32
>> 8) & BASE64_ENC_BITMASK
] : BASE64_PADDING_CHAR
;
132 spdk_base64_encode(char *dst
, const void *src
, size_t src_len
)
134 return _spdk_base64_encode(dst
, base64_enc_table
, src
, src_len
);
138 spdk_base64_urlsafe_encode(char *dst
, const void *src
, size_t src_len
)
140 return _spdk_base64_encode(dst
, base64_urfsafe_enc_table
, src
, src_len
);
144 _spdk_base64_decode(void *dst
, size_t *_dst_len
, const uint8_t *dec_table
, const char *src
)
146 size_t src_strlen
, dst_len
;
148 const uint8_t *src_in
;
156 src_strlen
= strlen(src
);
158 /* strlen of src should be 4n */
159 if (src_strlen
== 0 || src_strlen
% 4 != 0) {
163 /* Consider Base64 padding, it at most has 2 padding characters. */
164 for (i
= 0; i
< 2; i
++) {
165 if (src
[src_strlen
- 1] != BASE64_PADDING_CHAR
) {
171 /* strlen of src without padding shouldn't be 4n+1 */
172 if (src_strlen
== 0 || src_strlen
% 4 == 1) {
176 dst_len
= spdk_base64_get_decoded_len(src_strlen
);
177 src_in
= (const uint8_t *) src
;
179 /* space of dst can be used by to_be32 */
180 while (src_strlen
> 4) {
181 tmp
[0] = dec_table
[*src_in
++];
182 tmp
[1] = dec_table
[*src_in
++];
183 tmp
[2] = dec_table
[*src_in
++];
184 tmp
[3] = dec_table
[*src_in
++];
186 if (tmp
[0] == 255 || tmp
[1] == 255 || tmp
[2] == 255 || tmp
[3] == 255) {
190 to_be32(dst
, tmp
[3] << 8 | tmp
[2] << 14 | tmp
[1] << 20 | tmp
[0] << 26);
196 /* space of dst is not enough to be used by to_be32 */
197 tmp
[0] = dec_table
[src_in
[0]];
198 tmp
[1] = dec_table
[src_in
[1]];
199 tmp
[2] = (src_strlen
>= 3) ? dec_table
[src_in
[2]] : 0;
200 tmp
[3] = (src_strlen
== 4) ? dec_table
[src_in
[3]] : 0;
201 tail_len
= src_strlen
- 1;
203 if (tmp
[0] == 255 || tmp
[1] == 255 || tmp
[2] == 255 || tmp
[3] == 255) {
207 to_be32(&tmp
[3], tmp
[3] << 8 | tmp
[2] << 14 | tmp
[1] << 20 | tmp
[0] << 26);
208 memcpy(dst
, (uint8_t *)&tmp
[3], tail_len
);
210 /* Assign pointers */
219 spdk_base64_decode(void *dst
, size_t *dst_len
, const char *src
)
221 return _spdk_base64_decode(dst
, dst_len
, base64_dec_table
, src
);
225 spdk_base64_urlsafe_decode(void *dst
, size_t *dst_len
, const char *src
)
227 return _spdk_base64_decode(dst
, dst_len
, base64_urlsafe_dec_table
, src
);