mod b64 oke

master
Avril 4 years ago
parent 5e31143270
commit e120cd547d
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -5,27 +5,43 @@ use std::{
borrow::Borrow, borrow::Borrow,
fmt, fmt,
error, error,
convert::TryFrom,
}; };
use regex::{ use regex::{
Regex, Regex,
}; };
const BASE64_VALIDATE_RE_STR: &'static str = r#"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"#; const BASE64_VALIDATE_RE_STR: &'static str = r#"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"#;
const MOD_BASE64_VALIDATE_RE_STR: &'static str = r#"^(?:[-A-Za-z0-9_]{4})*(?:[-_A-Za-z0-9]{2}==|[-_A-Za-z0-9]{3}=)?$"#;
lazy_static!{ lazy_static!{
static ref BASE64_CONV_TABLE: smallmap::Map<char, char> = smallmap![ static ref BASE64_CONV_TABLE: smallmap::Map<char, char> = smallmap![
{'/' => '_'}, {'/' => '_'},
{'+' => 'ł'}, {'+' => '-'},
{'=' => '-'},
]; ];
static ref BASE64_CONV_TABLE_REV: smallmap::Map<char, char> = BASE64_CONV_TABLE.clone().reverse(); static ref BASE64_CONV_TABLE_REV: smallmap::Map<char, char> = BASE64_CONV_TABLE.clone().reverse();
static ref BASE64_VALIDATE_REGEX: Regex = Regex::new(BASE64_VALIDATE_RE_STR).expect("Failed to compile base64 validation regex"); static ref BASE64_VALIDATE_REGEX: Regex = Regex::new(BASE64_VALIDATE_RE_STR).expect("Failed to compile base64 validation regex");
static ref MOD_BASE64_VALIDATE_REGEX: Regex = Regex::new(MOD_BASE64_VALIDATE_RE_STR).expect("Failed to compile modified base64 validation regex");
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Base64Error<T>(T); pub struct Base64Error<T>(T);
impl<T> Base64Error<T>
{
/// The invalid value of this error
pub fn value(&self) -> &T
{
&self.0
}
/// Consume into the invalid value from this instance
#[inline] pub fn into_inner(self) -> T
{
self.0
}
}
impl<T> error::Error for Base64Error<T> impl<T> error::Error for Base64Error<T>
where T: AsRef<str> + fmt::Debug{} where T: AsRef<str> + fmt::Debug{}
impl<T> fmt::Display for Base64Error<T> impl<T> fmt::Display for Base64Error<T>
@ -52,7 +68,7 @@ impl fmt::Display for ModifiedBase64String
impl ModifiedBase64String impl ModifiedBase64String
{ {
fn from_base64_unchecked(string: &str) -> Self #[inline(always)] fn from_base64_unchecked(string: &str) -> Self
{ {
Self(conv_str(&BASE64_CONV_TABLE, string).collect()) Self(conv_str(&BASE64_CONV_TABLE, string).collect())
} }
@ -63,6 +79,22 @@ impl ModifiedBase64String
conv_char_iter(&BASE64_CONV_TABLE_REV, self.0.chars()).collect() conv_char_iter(&BASE64_CONV_TABLE_REV, self.0.chars()).collect()
} }
/// Consume into the inner modified base64 string
pub fn into_string(self) -> String
{
self.0
}
/// Create an instance from a modified base64 string
pub fn new(from: String) -> Result<Self, Base64Error<String>>
{
if MOD_BASE64_VALIDATE_REGEX.is_match(from.as_str()) {
Ok(Self(from))
} else {
Err(Base64Error(from))
}
}
/// Try to convert a base64 string into a modified base64 string /// Try to convert a base64 string into a modified base64 string
pub fn try_from_base64<T: AsRef<str>>(base64: T) -> Result<Self, Base64Error<T>> pub fn try_from_base64<T: AsRef<str>>(base64: T) -> Result<Self, Base64Error<T>>
{ {
@ -115,6 +147,24 @@ impl AsRef<str> for ModifiedBase64String
} }
} }
impl TryFrom<String> for ModifiedBase64String
{
type Error = Base64Error<String>;
#[inline] fn try_from(from: String) -> Result<Self, Self::Error>
{
Self::try_from_base64(from)
}
}
impl From<ModifiedBase64String> for String
{
#[inline] fn from(from: ModifiedBase64String) -> Self
{
from.into_base64()
}
}
/// Convert this string with a specified char map. Returns a `char` yielding iterator. /// Convert this string with a specified char map. Returns a `char` yielding iterator.
#[inline] pub fn conv_str<'a, 'b>(table: &'b smallmap::Map<char, char>, string: &'a (impl AsRef<str> + ?Sized)) -> CharSubstituteIter<'b, std::str::Chars<'a>> #[inline] pub fn conv_str<'a, 'b>(table: &'b smallmap::Map<char, char>, string: &'a (impl AsRef<str> + ?Sized)) -> CharSubstituteIter<'b, std::str::Chars<'a>>
@ -131,3 +181,19 @@ where I: IntoIterator<Item=T>,
{ {
iter.replace_chars(table) iter.replace_chars(table)
} }
#[cfg(test)]
mod tests
{
#[test]
fn mod_base64_enc_dec()
{
let mut value = [0u8; 512];
getrandom::getrandom(&mut value[..]).expect("setup failed");
let md = super::ModifiedBase64String::encode(&value[..]);
println!("e-md: {:?}", md);
let ou = md.decode_new();
assert_eq!(&ou[..], &value[..]);
}
}

Loading…
Cancel
Save