Skip to content

Commit

Permalink
cleanup base32
Browse files Browse the repository at this point in the history
  • Loading branch information
jbesraa committed Apr 23, 2023
1 parent ddf0490 commit 3e46d4c
Showing 1 changed file with 27 additions and 64 deletions.
91 changes: 27 additions & 64 deletions lightning/src/util/base32.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
/// Copied from https://crates.io/crates/base32 v0.4.0
/// License: MIT or Apache-2.0
use std::cmp::min;
// Source: https://crates.io/crates/base32 v0.4.0
// License: MIT or Apache-2.0
// Copyright (c) 2015 The base32 Developers
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// (reference https://github.com/andreasots/base32/blob/master/LICENSE-MIT)

#[derive(Copy, Clone)]
pub enum Alphabet {
Expand Down Expand Up @@ -65,21 +83,18 @@ const CROCKFORD_INV_ALPHABET: [i8; 43] = [

// Decode a base32 string into a byte vector.
pub fn decode(alphabet: Alphabet, data: &str) -> Option<Vec<u8>> {
if !data.is_ascii() {
return None;
}
let data = data.as_bytes();
let alphabet = match alphabet {
Alphabet::RFC4648 { .. } => RFC4648_INV_ALPHABET,
Alphabet::Crockford => CROCKFORD_INV_ALPHABET,
};
let mut unpadded_data_length = data.len();
for i in 1..min(6, data.len()) + 1 {
if data[data.len() - i] != b'=' {
break;
}
unpadded_data_length -= 1;
}
data.iter().rev().take(6).for_each(|&c| {
if c != b'=' {
return;
}
unpadded_data_length -= 1;
});
let output_length = unpadded_data_length * 5 / 8;
let mut ret = Vec::with_capacity((output_length + 4) / 5 * 5);
for chunk in data.chunks(8) {
Expand Down Expand Up @@ -108,22 +123,13 @@ pub fn decode(alphabet: Alphabet, data: &str) -> Option<Vec<u8>> {
mod test {
use super::Alphabet::{Crockford, RFC4648};
use super::{decode, encode};
use quickcheck::{self, Arbitrary, Gen};
use std::fmt::{Debug, Error, Formatter};

#[derive(Clone)]
struct B32 {
c: u8,
}

impl Arbitrary for B32 {
fn arbitrary(g: &mut Gen) -> B32 {
B32 {
c: *g.choose(b"0123456789ABCDEFGHJKMNPQRSTVWXYZ").unwrap(),
}
}
}

impl Debug for B32 {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
(self.c as char).fmt(f)
Expand Down Expand Up @@ -216,49 +222,6 @@ mod test {
}
}

#[test]
fn invertible_crockford() {
fn test(data: Vec<u8>) -> bool {
decode(Crockford, encode(Crockford, data.as_ref()).as_ref()).unwrap() == data
}
quickcheck::quickcheck(test as fn(Vec<u8>) -> bool)
}

#[test]
fn invertible_rfc4648() {
fn test(data: Vec<u8>) -> bool {
decode(
RFC4648 { padding: true },
encode(RFC4648 { padding: true }, data.as_ref()).as_ref(),
)
.unwrap()
== data
}
quickcheck::quickcheck(test as fn(Vec<u8>) -> bool)
}
#[test]
fn invertible_unpadded_rfc4648() {
fn test(data: Vec<u8>) -> bool {
decode(
RFC4648 { padding: false },
encode(RFC4648 { padding: false }, data.as_ref()).as_ref(),
)
.unwrap()
== data
}
quickcheck::quickcheck(test as fn(Vec<u8>) -> bool)
}

#[test]
fn lower_case() {
fn test(data: Vec<B32>) -> bool {
let data: String = data.iter().map(|e| e.c as char).collect();
decode(Crockford, data.as_ref())
== decode(Crockford, data.to_ascii_lowercase().as_ref())
}
quickcheck::quickcheck(test as fn(Vec<B32>) -> bool)
}

#[test]
#[allow(non_snake_case)]
fn iIlL1_oO0() {
Expand Down

0 comments on commit 3e46d4c

Please sign in to comment.