|
1 |
| -/// Copied from https://crates.io/crates/base32 v0.4.0 |
2 |
| -/// License: MIT or Apache-2.0 |
3 |
| -use std::cmp::min; |
| 1 | +// Source: https://crates.io/crates/base32 v0.4.0 |
| 2 | +// License: MIT or Apache-2.0 |
| 3 | +// Copyright (c) 2015 The base32 Developers |
| 4 | +// Permission is hereby granted, free of charge, to any person obtaining a copy |
| 5 | +// of this software and associated documentation files (the "Software"), to deal |
| 6 | +// in the Software without restriction, including without limitation the rights |
| 7 | +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 8 | +// copies of the Software, and to permit persons to whom the Software is |
| 9 | +// furnished to do so, subject to the following conditions: |
| 10 | + |
| 11 | +// The above copyright notice and this permission notice shall be included in all |
| 12 | +// copies or substantial portions of the Software. |
| 13 | + |
| 14 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 15 | +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 16 | +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 17 | +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 18 | +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 19 | +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 20 | +// SOFTWARE. |
| 21 | +// (reference https://github.com/andreasots/base32/blob/master/LICENSE-MIT) |
4 | 22 |
|
5 | 23 | #[derive(Copy, Clone)]
|
6 | 24 | pub enum Alphabet {
|
@@ -65,21 +83,18 @@ const CROCKFORD_INV_ALPHABET: [i8; 43] = [
|
65 | 83 |
|
66 | 84 | // Decode a base32 string into a byte vector.
|
67 | 85 | pub fn decode(alphabet: Alphabet, data: &str) -> Option<Vec<u8>> {
|
68 |
| - if !data.is_ascii() { |
69 |
| - return None; |
70 |
| - } |
71 | 86 | let data = data.as_bytes();
|
72 | 87 | let alphabet = match alphabet {
|
73 | 88 | Alphabet::RFC4648 { .. } => RFC4648_INV_ALPHABET,
|
74 | 89 | Alphabet::Crockford => CROCKFORD_INV_ALPHABET,
|
75 | 90 | };
|
76 | 91 | let mut unpadded_data_length = data.len();
|
77 |
| - for i in 1..min(6, data.len()) + 1 { |
78 |
| - if data[data.len() - i] != b'=' { |
79 |
| - break; |
80 |
| - } |
81 |
| - unpadded_data_length -= 1; |
82 |
| - } |
| 92 | + data.iter().rev().take(6).for_each(|&c| { |
| 93 | + if c != b'=' { |
| 94 | + return; |
| 95 | + } |
| 96 | + unpadded_data_length -= 1; |
| 97 | + }); |
83 | 98 | let output_length = unpadded_data_length * 5 / 8;
|
84 | 99 | let mut ret = Vec::with_capacity((output_length + 4) / 5 * 5);
|
85 | 100 | for chunk in data.chunks(8) {
|
@@ -108,22 +123,13 @@ pub fn decode(alphabet: Alphabet, data: &str) -> Option<Vec<u8>> {
|
108 | 123 | mod test {
|
109 | 124 | use super::Alphabet::{Crockford, RFC4648};
|
110 | 125 | use super::{decode, encode};
|
111 |
| - use quickcheck::{self, Arbitrary, Gen}; |
112 | 126 | use std::fmt::{Debug, Error, Formatter};
|
113 | 127 |
|
114 | 128 | #[derive(Clone)]
|
115 | 129 | struct B32 {
|
116 | 130 | c: u8,
|
117 | 131 | }
|
118 | 132 |
|
119 |
| - impl Arbitrary for B32 { |
120 |
| - fn arbitrary(g: &mut Gen) -> B32 { |
121 |
| - B32 { |
122 |
| - c: *g.choose(b"0123456789ABCDEFGHJKMNPQRSTVWXYZ").unwrap(), |
123 |
| - } |
124 |
| - } |
125 |
| - } |
126 |
| - |
127 | 133 | impl Debug for B32 {
|
128 | 134 | fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
129 | 135 | (self.c as char).fmt(f)
|
@@ -216,49 +222,6 @@ mod test {
|
216 | 222 | }
|
217 | 223 | }
|
218 | 224 |
|
219 |
| - #[test] |
220 |
| - fn invertible_crockford() { |
221 |
| - fn test(data: Vec<u8>) -> bool { |
222 |
| - decode(Crockford, encode(Crockford, data.as_ref()).as_ref()).unwrap() == data |
223 |
| - } |
224 |
| - quickcheck::quickcheck(test as fn(Vec<u8>) -> bool) |
225 |
| - } |
226 |
| - |
227 |
| - #[test] |
228 |
| - fn invertible_rfc4648() { |
229 |
| - fn test(data: Vec<u8>) -> bool { |
230 |
| - decode( |
231 |
| - RFC4648 { padding: true }, |
232 |
| - encode(RFC4648 { padding: true }, data.as_ref()).as_ref(), |
233 |
| - ) |
234 |
| - .unwrap() |
235 |
| - == data |
236 |
| - } |
237 |
| - quickcheck::quickcheck(test as fn(Vec<u8>) -> bool) |
238 |
| - } |
239 |
| - #[test] |
240 |
| - fn invertible_unpadded_rfc4648() { |
241 |
| - fn test(data: Vec<u8>) -> bool { |
242 |
| - decode( |
243 |
| - RFC4648 { padding: false }, |
244 |
| - encode(RFC4648 { padding: false }, data.as_ref()).as_ref(), |
245 |
| - ) |
246 |
| - .unwrap() |
247 |
| - == data |
248 |
| - } |
249 |
| - quickcheck::quickcheck(test as fn(Vec<u8>) -> bool) |
250 |
| - } |
251 |
| - |
252 |
| - #[test] |
253 |
| - fn lower_case() { |
254 |
| - fn test(data: Vec<B32>) -> bool { |
255 |
| - let data: String = data.iter().map(|e| e.c as char).collect(); |
256 |
| - decode(Crockford, data.as_ref()) |
257 |
| - == decode(Crockford, data.to_ascii_lowercase().as_ref()) |
258 |
| - } |
259 |
| - quickcheck::quickcheck(test as fn(Vec<B32>) -> bool) |
260 |
| - } |
261 |
| - |
262 | 225 | #[test]
|
263 | 226 | #[allow(non_snake_case)]
|
264 | 227 | fn iIlL1_oO0() {
|
|
0 commit comments