22 static void b85prep(void) |
22 static void b85prep(void) |
23 { |
23 { |
24 unsigned i; |
24 unsigned i; |
25 |
25 |
26 memset(b85dec, 0, sizeof(b85dec)); |
26 memset(b85dec, 0, sizeof(b85dec)); |
27 for (i = 0; i < sizeof(b85chars); i++) |
27 for (i = 0; i < sizeof(b85chars); i++) { |
28 b85dec[(int)(b85chars[i])] = i + 1; |
28 b85dec[(int)(b85chars[i])] = i + 1; |
|
29 } |
29 } |
30 } |
30 |
31 |
31 static PyObject *b85encode(PyObject *self, PyObject *args) |
32 static PyObject *b85encode(PyObject *self, PyObject *args) |
32 { |
33 { |
33 const unsigned char *text; |
34 const unsigned char *text; |
35 char *dst; |
36 char *dst; |
36 Py_ssize_t len, olen, i; |
37 Py_ssize_t len, olen, i; |
37 unsigned int acc, val, ch; |
38 unsigned int acc, val, ch; |
38 int pad = 0; |
39 int pad = 0; |
39 |
40 |
40 if (!PyArg_ParseTuple(args, PY23("s#|i", "y#|i"), &text, &len, &pad)) |
41 if (!PyArg_ParseTuple(args, PY23("s#|i", "y#|i"), &text, &len, &pad)) { |
41 return NULL; |
42 return NULL; |
42 |
43 } |
43 if (pad) |
44 |
|
45 if (pad) { |
44 olen = ((len + 3) / 4 * 5) - 3; |
46 olen = ((len + 3) / 4 * 5) - 3; |
45 else { |
47 } else { |
46 olen = len % 4; |
48 olen = len % 4; |
47 if (olen) |
49 if (olen) { |
48 olen++; |
50 olen++; |
|
51 } |
49 olen += len / 4 * 5; |
52 olen += len / 4 * 5; |
50 } |
53 } |
51 if (!(out = PyBytes_FromStringAndSize(NULL, olen + 3))) |
54 if (!(out = PyBytes_FromStringAndSize(NULL, olen + 3))) { |
52 return NULL; |
55 return NULL; |
|
56 } |
53 |
57 |
54 dst = PyBytes_AsString(out); |
58 dst = PyBytes_AsString(out); |
55 |
59 |
56 while (len) { |
60 while (len) { |
57 acc = 0; |
61 acc = 0; |
58 for (i = 24; i >= 0; i -= 8) { |
62 for (i = 24; i >= 0; i -= 8) { |
59 ch = *text++; |
63 ch = *text++; |
60 acc |= ch << i; |
64 acc |= ch << i; |
61 if (--len == 0) |
65 if (--len == 0) { |
62 break; |
66 break; |
|
67 } |
63 } |
68 } |
64 for (i = 4; i >= 0; i--) { |
69 for (i = 4; i >= 0; i--) { |
65 val = acc % 85; |
70 val = acc % 85; |
66 acc /= 85; |
71 acc /= 85; |
67 dst[i] = b85chars[val]; |
72 dst[i] = b85chars[val]; |
68 } |
73 } |
69 dst += 5; |
74 dst += 5; |
70 } |
75 } |
71 |
76 |
72 if (!pad) |
77 if (!pad) { |
73 _PyBytes_Resize(&out, olen); |
78 _PyBytes_Resize(&out, olen); |
|
79 } |
74 |
80 |
75 return out; |
81 return out; |
76 } |
82 } |
77 |
83 |
78 static PyObject *b85decode(PyObject *self, PyObject *args) |
84 static PyObject *b85decode(PyObject *self, PyObject *args) |
82 char *dst; |
88 char *dst; |
83 Py_ssize_t len, i, j, olen, cap; |
89 Py_ssize_t len, i, j, olen, cap; |
84 int c; |
90 int c; |
85 unsigned int acc; |
91 unsigned int acc; |
86 |
92 |
87 if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &text, &len)) |
93 if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &text, &len)) { |
88 return NULL; |
94 return NULL; |
|
95 } |
89 |
96 |
90 olen = len / 5 * 4; |
97 olen = len / 5 * 4; |
91 i = len % 5; |
98 i = len % 5; |
92 if (i) |
99 if (i) { |
93 olen += i - 1; |
100 olen += i - 1; |
94 if (!(out = PyBytes_FromStringAndSize(NULL, olen))) |
101 } |
95 return NULL; |
102 if (!(out = PyBytes_FromStringAndSize(NULL, olen))) { |
|
103 return NULL; |
|
104 } |
96 |
105 |
97 dst = PyBytes_AsString(out); |
106 dst = PyBytes_AsString(out); |
98 |
107 |
99 i = 0; |
108 i = 0; |
100 while (i < len) { |
109 while (i < len) { |
101 acc = 0; |
110 acc = 0; |
102 cap = len - i - 1; |
111 cap = len - i - 1; |
103 if (cap > 4) |
112 if (cap > 4) { |
104 cap = 4; |
113 cap = 4; |
|
114 } |
105 for (j = 0; j < cap; i++, j++) { |
115 for (j = 0; j < cap; i++, j++) { |
106 c = b85dec[(int)*text++] - 1; |
116 c = b85dec[(int)*text++] - 1; |
107 if (c < 0) { |
117 if (c < 0) { |
108 PyErr_Format( |
118 PyErr_Format( |
109 PyExc_ValueError, |
119 PyExc_ValueError, |
134 acc += c; |
144 acc += c; |
135 } |
145 } |
136 |
146 |
137 cap = olen < 4 ? olen : 4; |
147 cap = olen < 4 ? olen : 4; |
138 olen -= cap; |
148 olen -= cap; |
139 for (j = 0; j < 4 - cap; j++) |
149 for (j = 0; j < 4 - cap; j++) { |
140 acc *= 85; |
150 acc *= 85; |
141 if (cap && cap < 4) |
151 } |
|
152 if (cap && cap < 4) { |
142 acc += 0xffffff >> (cap - 1) * 8; |
153 acc += 0xffffff >> (cap - 1) * 8; |
|
154 } |
143 for (j = 0; j < cap; j++) { |
155 for (j = 0; j < cap; j++) { |
144 acc = (acc << 8) | (acc >> 24); |
156 acc = (acc << 8) | (acc >> 24); |
145 *dst++ = acc; |
157 *dst++ = acc; |
146 } |
158 } |
147 } |
159 } |