-
Notifications
You must be signed in to change notification settings - Fork 11
/
base32.c
119 lines (101 loc) · 3.33 KB
/
base32.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
* Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
* Mostly rewritten 2009 J.A.Bezemer@opensourcepartners.nl
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include "base32.h"
static const char cb32[] =
"abcdefghijklmnopqrstuvwxyz234567";
static const char cb32_ucase[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
static unsigned char rev32[256];
static int reverse_init = 0;
int base32_encode(char *buf, size_t *buflen, const void *data, size_t size)
/*
* Fills *buf with max. *buflen characters, encoding size bytes of *data.
*
* NOTE: *buf space should be at least 1 byte _more_ than *buflen
* to hold the trailing '\0'.
*
* return value : #bytes filled in buf (excluding \0)
* sets *buflen to : #bytes encoded from data
*/
{
unsigned char *udata = (unsigned char *) data;
int iout = 0; /* to-be-filled output char */
int iin = 0; /* one more than last input byte that can be
successfully decoded */
/* Note: Don't bother to optimize manually. GCC optimizes
better(!) when using simplistic array indexing. */
while (1) {
if (iout >= *buflen || iin >= size)
break;
buf[iout] = cb32[((udata[iin] & 0xf8) >> 3)];
iout++;
if (iout >= *buflen || iin >= size) {
iout--; /* previous char is useless */
break;
}
buf[iout] = cb32[((udata[iin] & 0x07) << 2) |
((iin + 1 < size) ?
((udata[iin + 1] & 0xc0) >> 6) : 0)];
iin++; /* 0 complete, iin=1 */
iout++;
if (iout >= *buflen || iin >= size)
break;
buf[iout] = cb32[((udata[iin] & 0x3e) >> 1)];
iout++;
if (iout >= *buflen || iin >= size) {
iout--; /* previous char is useless */
break;
}
buf[iout] = cb32[((udata[iin] & 0x01) << 4) |
((iin + 1 < size) ?
((udata[iin + 1] & 0xf0) >> 4) : 0)];
iin++; /* 1 complete, iin=2 */
iout++;
if (iout >= *buflen || iin >= size)
break;
buf[iout] = cb32[((udata[iin] & 0x0f) << 1) |
((iin + 1 < size) ?
((udata[iin + 1] & 0x80) >> 7) : 0)];
iin++; /* 2 complete, iin=3 */
iout++;
if (iout >= *buflen || iin >= size)
break;
buf[iout] = cb32[((udata[iin] & 0x7c) >> 2)];
iout++;
if (iout >= *buflen || iin >= size) {
iout--; /* previous char is useless */
break;
}
buf[iout] = cb32[((udata[iin] & 0x03) << 3) |
((iin + 1 < size) ?
((udata[iin + 1] & 0xe0) >> 5) : 0)];
iin++; /* 3 complete, iin=4 */
iout++;
if (iout >= *buflen || iin >= size)
break;
buf[iout] = cb32[((udata[iin] & 0x1f))];
iin++; /* 4 complete, iin=5 */
iout++;
}
buf[iout] = '\0';
/* store number of bytes from data that was used */
*buflen = iin;
return iout;
}