]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * basE91 encoding/decoding routines | |
3 | * | |
4 | * Copyright (c) 2000-2006 Joachim Henke | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions are met: | |
9 | * | |
10 | * - Redistributions of source code must retain the above copyright notice, | |
11 | * this list of conditions and the following disclaimer. | |
12 | * - Redistributions in binary form must reproduce the above copyright notice, | |
13 | * this list of conditions and the following disclaimer in the documentation | |
14 | * and/or other materials provided with the distribution. | |
15 | * - Neither the name of Joachim Henke nor the names of his contributors may | |
16 | * be used to endorse or promote products derived from this software without | |
17 | * specific prior written permission. | |
18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | |
31 | ||
32 | #include "base91.h" | |
33 | ||
34 | const unsigned char enctab[91] = { | |
35 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', | |
36 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', | |
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 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', '#', '$', | |
40 | '%', '&', '(', ')', '*', '+', ',', '.', '/', ':', ';', '<', '=', | |
41 | '>', '?', '@', '[', ']', '^', '_', '`', '{', '|', '}', '~', '"' | |
42 | }; | |
43 | const unsigned char dectab[256] = { | |
44 | 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, | |
45 | 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, | |
46 | 91, 62, 90, 63, 64, 65, 66, 91, 67, 68, 69, 70, 71, 91, 72, 73, | |
47 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 74, 75, 76, 77, 78, 79, | |
48 | 80, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, | |
49 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 81, 91, 82, 83, 84, | |
50 | 85, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, | |
51 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 86, 87, 88, 89, 91, | |
52 | 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, | |
53 | 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, | |
54 | 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, | |
55 | 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, | |
56 | 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, | |
57 | 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, | |
58 | 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, | |
59 | 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91 | |
60 | }; | |
61 | ||
62 | void basE91_init(struct basE91 *b) | |
63 | { | |
64 | b->queue = 0; | |
65 | b->nbits = 0; | |
66 | b->val = -1; | |
67 | } | |
68 | ||
69 | size_t basE91_encode(struct basE91 *b, const void *i, size_t len, void *o) | |
70 | { | |
71 | const unsigned char *ib = i; | |
72 | unsigned char *ob = o; | |
73 | size_t n = 0; | |
74 | ||
75 | while (len--) { | |
76 | b->queue |= *ib++ << b->nbits; | |
77 | b->nbits += 8; | |
78 | if (b->nbits > 13) { /* enough bits in queue */ | |
79 | unsigned int val = b->queue & 8191; | |
80 | ||
81 | if (val > 88) { | |
82 | b->queue >>= 13; | |
83 | b->nbits -= 13; | |
84 | } else { /* we can take 14 bits */ | |
85 | val = b->queue & 16383; | |
86 | b->queue >>= 14; | |
87 | b->nbits -= 14; | |
88 | } | |
89 | ob[n++] = enctab[val % 91]; | |
90 | ob[n++] = enctab[val / 91]; | |
91 | } | |
92 | } | |
93 | ||
94 | return n; | |
95 | } | |
96 | ||
97 | /* process remaining bits from bit queue; write up to 2 bytes */ | |
98 | ||
99 | size_t basE91_encode_end(struct basE91 *b, void *o) | |
100 | { | |
101 | unsigned char *ob = o; | |
102 | size_t n = 0; | |
103 | ||
104 | if (b->nbits) { | |
105 | ob[n++] = enctab[b->queue % 91]; | |
106 | if (b->nbits > 7 || b->queue > 90) | |
107 | ob[n++] = enctab[b->queue / 91]; | |
108 | } | |
109 | b->queue = 0; | |
110 | b->nbits = 0; | |
111 | b->val = -1; | |
112 | ||
113 | return n; | |
114 | } | |
115 | ||
116 | size_t basE91_decode(struct basE91 *b, const void *i, size_t len, void *o) | |
117 | { | |
118 | const unsigned char *ib = i; | |
119 | unsigned char *ob = o; | |
120 | size_t n = 0; | |
121 | unsigned int d; | |
122 | ||
123 | while (len--) { | |
124 | d = dectab[*ib++]; | |
125 | if (d == 91) | |
126 | continue; /* ignore non-alphabet chars */ | |
127 | if (b->val == -1) | |
128 | b->val = d; /* start next value */ | |
129 | else { | |
130 | b->val += d * 91; | |
131 | b->queue |= b->val << b->nbits; | |
132 | b->nbits += (b->val & 8191) > 88 ? 13 : 14; | |
133 | do { | |
134 | ob[n++] = b->queue; | |
135 | b->queue >>= 8; | |
136 | b->nbits -= 8; | |
137 | } while (b->nbits > 7); | |
138 | b->val = -1; /* mark value complete */ | |
139 | } | |
140 | } | |
141 | ||
142 | return n; | |
143 | } | |
144 | ||
145 | /* process remaining bits; write at most 1 byte */ | |
146 | ||
147 | size_t basE91_decode_end(struct basE91 *b, void *o) | |
148 | { | |
149 | unsigned char *ob = o; | |
150 | size_t n = 0; | |
151 | ||
152 | if (b->val != -1) | |
153 | ob[n++] = b->queue | b->val << b->nbits; | |
154 | b->queue = 0; | |
155 | b->nbits = 0; | |
156 | b->val = -1; | |
157 | ||
158 | return n; | |
159 | } |