goxoy-hash 0.0.1

Goxoy Hash Library (sasha, md5, sha1, sha256, sha512, blake3, blake2b, blake2s, ripemd160, whirlpool)
Documentation
#![warn(unused_assignments)]
#![warn(unreachable_patterns)]
use crypto::digest::Digest;

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum HashKind {
    SASHA = 0,

    MD5,

    SHA1,
    SHA256,
    SHA512,

    BLAKE2B,
    BLAKE2S,
    BLAKE3,

    RIPEMD160,

    WHIRLPOOL,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Hash {
    pub hash_type: HashKind,
}

trait SubStr {
    fn sub_strings(&self, length: usize) -> Vec<&str>;
}

impl SubStr for str {
    fn sub_strings(&self, sub_len: usize) -> Vec<&str> {
        let mut subs = Vec::with_capacity(self.len() / sub_len);
        let mut iter = self.chars();
        let mut pos = 0;

        while pos < self.len() {
            let mut len = 0;
            for ch in iter.by_ref().take(sub_len) {
                len += ch.len_utf8();
            }
            subs.push(&self[pos..pos + len]);
            pos += len;
        }
        subs
    }
}

impl HashKind {
    pub fn length(&self) -> u16 {
        match self {
            HashKind::SASHA => 240,
            HashKind::MD5 => 32,

            HashKind::SHA1 => 40,
            HashKind::SHA256 => 64,
            HashKind::SHA512 => 128,

            HashKind::BLAKE2B => 128,
            HashKind::BLAKE2S => 64,
            HashKind::BLAKE3 => 64,

            HashKind::RIPEMD160 => 40,
            HashKind::WHIRLPOOL => 128,
        }
    }
}

pub trait U8ToHashKind {
    fn to_hash_kind(&self) -> HashKind;
}

impl U8ToHashKind for u8 {
    fn to_hash_kind(&self) -> HashKind {
        match self {
            0 => HashKind::SASHA,
            1 => HashKind::MD5,
            2 => HashKind::SHA1,
            3 => HashKind::SHA256,
            4 => HashKind::SHA512,
            5 => HashKind::BLAKE2B,
            6 => HashKind::BLAKE2B,
            7 => HashKind::BLAKE3,
            8 => HashKind::RIPEMD160,
            9 => HashKind::WHIRLPOOL,
            _ => HashKind::SASHA,
        }
    }
}

impl Hash {
    pub fn calculate(hash_type: HashKind, hash_data: &str) -> String {
        match hash_type {
            HashKind::SASHA => {
                let blake2b_temp_result = Self::calculate(HashKind::BLAKE2B, hash_data);
                let split_blake2b = &blake2b_temp_result.sub_strings(16);

                let md5_temp_result = Self::calculate(HashKind::MD5, hash_data);
                let split_md5 = &md5_temp_result.sub_strings(4);

                let sha1_temp_result = Self::calculate(HashKind::SHA1, hash_data);
                let split_sha1 = &sha1_temp_result.sub_strings(5);

                let ripemd160_temp_result = Self::calculate(HashKind::RIPEMD160, hash_data);
                let split_ripemd160 = &ripemd160_temp_result.sub_strings(5);

                let mut result_val = String::new();
                for x in 0..8 {
                    if x < 4 {
                        result_val = result_val
                            + split_blake2b[x]
                            + split_md5[x]
                            + split_sha1[x]
                            + split_ripemd160[x];
                    } else {
                        result_val = result_val
                            + split_ripemd160[x]
                            + split_sha1[x]
                            + split_md5[x]
                            + split_blake2b[x];
                    }
                }
                return result_val;
            }
            HashKind::MD5 => {
                let mut hash_obj = crypto::md5::Md5::new();
                hash_obj.input_str(hash_data);
                return hash_obj.result_str();
            }
            HashKind::SHA1 => {
                let mut hash_obj = crypto::sha1::Sha1::new();
                hash_obj.input_str(hash_data);
                return hash_obj.result_str();
            }
            HashKind::SHA256 => {
                let mut hash_obj = crypto::sha2::Sha256::new();
                hash_obj.input_str(hash_data);
                return hash_obj.result_str();
            }
            HashKind::SHA512 => {
                let mut hash_obj = crypto::sha2::Sha512::new();
                hash_obj.input_str(hash_data);
                return hash_obj.result_str();
            }
            HashKind::BLAKE2B => {
                let mut hash_obj = crypto::blake2b::Blake2b::new(64);
                hash_obj.input_str(hash_data);
                return hash_obj.result_str();
            }
            HashKind::RIPEMD160 => {
                let mut hash_obj = crypto::ripemd160::Ripemd160::new();
                hash_obj.input_str(hash_data);
                return hash_obj.result_str();
            }
            HashKind::WHIRLPOOL => {
                let mut hash_obj = crypto::whirlpool::Whirlpool::new();
                hash_obj.input_str(hash_data);
                return hash_obj.result_str();
            }
            HashKind::BLAKE2S => {
                let mut hash_obj = crypto::blake2s::Blake2s::new(32);
                hash_obj.input_str(hash_data);
                return hash_obj.result_str();
            }
            HashKind::BLAKE3 => {
                return blake3::hash(hash_data.as_bytes()).to_string();
            }
        }
    }

    pub fn wallet_calculation(in_data: &str) -> String {
        const DEFAULT_HEX_ALPHABET_STRING: &str = "0123456789abcdef";
        const SIMPLE_HASH_ALPHABET_FOR_HEX_RESULT: &str = "fedcba9876543210";

        Self::replace_char(
            Self::calculate(HashKind::SASHA, &in_data.chars().rev().collect::<String>()),
            DEFAULT_HEX_ALPHABET_STRING.to_string(),
            SIMPLE_HASH_ALPHABET_FOR_HEX_RESULT.to_string(),
        )
    }

    fn replace_char(source_text: String, from_text: String, to_text: String) -> String {
        let mut input = source_text.chars().collect::<Vec<char>>();
        let mut replaced: Vec<bool> = Vec::with_capacity(input.len());
        for _ in 0..input.len() {
            replaced.push(false);
        }
        for i in 0..from_text.len() {
            for j in 0..input.len() {
                if replaced[j] == false && input[j] == from_text.chars().nth(i).unwrap() {
                    input[j] = to_text.chars().nth(i).unwrap();
                    replaced[j] = true;
                }
            }
        }
        input.iter().collect::<String>()
    }
}

#[test]
fn md5_short_hash_test() {
    assert_eq!(
        "d8578edf8458ce06fbc5bb76a58c5ca4",
        Hash::calculate(HashKind::MD5, "qwerty")
    );
}
#[test]
fn md5_long_hash_test() {
    assert_eq!(
        "65be673803a67c8f37e9ec51dfb66bc0",
        Hash::calculate(HashKind::MD5, &"qwert".repeat(10))
    );
}
#[test]
fn sha1_short_hash_test() {
    assert_eq!(
        "b1b3773a05c0ed0176787a4f1574ff0075f7521e",
        Hash::calculate(HashKind::SHA1, "qwerty")
    );
}
#[test]
fn sha1_long_hash_test() {
    assert_eq!(
        "8ce2bfdafe27ef4c3d1fae9db2a2c428cd5c063a",
        Hash::calculate(HashKind::SHA1, &"qwert".repeat(10))
    );
}
#[test]
fn sha256_short_hash_test() {
    assert_eq!(
        "65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5",
        Hash::calculate(HashKind::SHA256, "qwerty")
    );
}
#[test]
fn sha256_long_hash_test() {
    assert_eq!(
        "a69a351e7de07f954b1ca107a1f38592fc35afe6ed625b80959311c8ce831d2b",
        Hash::calculate(HashKind::SHA256, &"qwert".repeat(20))
    );
}
#[test]
fn sha512_short_hash_test() {
    assert_eq!(
        "0dd3e512642c97ca3f747f9a76e374fbda73f9292823c0313be9d78add7cdd8f72235af0c553dd26797e78e1854edee0ae002f8aba074b066dfce1af114e32f8",
        Hash::calculate(HashKind::SHA512, "qwerty")
    );
}
#[test]
fn sha512_long_hash_test() {
    assert_eq!(
        "409b286f9e9be0eb9ffc6a89a96742c1d4e56bcc49441cc2e67f7c1aa3ab829bc48680bda8125cca10f18eea1d046420064fb69f82b6b1265581a0467c4d9318",
        Hash::calculate(HashKind::SHA512, &"qwert".repeat(40))
    );
}
#[test]
fn blake2b_short_hash_test() {
    assert_eq!(
        "9548a146e860a65a1aae6c7a9ee6143c52cf0fcd65db45e1773a4fa785bcb158c5827ec6f7fad3188409a4401a71c32a792fce997048684f77b598831eb81e21",
        Hash::calculate(HashKind::BLAKE2B, "qwerty")
    );
}
#[test]
fn blake2b_long_hash_test() {
    assert_eq!(
        "80472ae0730951dd5daccc2608ac4db554ee37609a205ec05124549d097b96b24138965329dfaa97c62bdd20b5a059b031c96070640744c3a0f6f5bc31167e5c",
        Hash::calculate(HashKind::BLAKE2B, &"qwert".repeat(40))
    );
}
#[test]
fn blake2s_short_hash_test() {
    assert_eq!(
        "4bb6d05aebc19ab25a7abfc3d283fc66b738f9295065fc684c23b16db775b662",
        Hash::calculate(HashKind::BLAKE2S, "qwerty")
    );
}
#[test]
fn blake2s_long_hash_test() {
    assert_eq!(
        "72b57e7bae1e4ff79940f04098cbb744908b35edf1caff494eaee3344488090d",
        Hash::calculate(HashKind::BLAKE2S, &"qwert".repeat(20))
    );
}
#[test]
fn blake3_short_hash_test() {
    assert_eq!(
        "305ff248441f66cdfe5f44be6ad896d366f32910748ed71d0d18f5467b817ce7",
        Hash::calculate(HashKind::BLAKE3, "qwerty")
    );
}
#[test]
fn blake3_long_hash_test() {
    assert_eq!(
        "2c0989aead13089f1272210c9f58c452f8e6f9c398e7b46ae819d082d01183f7",
        Hash::calculate(HashKind::BLAKE3, &"qwert".repeat(20))
    );
}
#[test]
fn ripemd160_short_hash_test() {
    assert_eq!(
        "3a0ede1791358f307ae1f211d3fc4acf677644d8",
        Hash::calculate(HashKind::RIPEMD160, "qwerty")
    );
}
#[test]
fn ripemd160_long_hash_test() {
    assert_eq!(
        "3c46f1b916f88d714395432743e2955d0f2743f2",
        Hash::calculate(HashKind::RIPEMD160, &"qwert".repeat(20))
    );
}
#[test]
fn whirlpool_short_hash_test() {
    assert_eq!(
        "4925da7da7a56260baf1c37925a8fa24e46ad8b107dcd21f44e39e4751bae1304fc70de7acb847ffa96126bb372de005f5320f1ede6f9df07c7d53f9c160f022", 
        Hash::calculate(HashKind::WHIRLPOOL, "qwerty")
    );
}
#[test]
fn whirlpool_long_hash_test() {
    assert_eq!(
        "e95a46ff079e3a37e6c099db9bc332a3473839a6139958f6d1ea08a37ab902709fe8fb02db4d68818a3c44ae78e60f785cb69f808af6a52b82e120465e2da8df", 
        Hash::calculate(HashKind::WHIRLPOOL, &"qwert".repeat(100))
    );
}
#[test]
fn sasha_short_hash_test() {
    assert_eq!(
        "9548a146e860a65ad857b1b373a0ed1aae6c7a9ee6143c8edf73a05e179152cf0fcd65db45e18458c0ed0358f3773a4fa785bcb158ce061767807ae1f211d7a4f1fbc5c5827ec6f7fad3183fc4a574ffbb768409a4401a71c32acf6770075fa58c792fce997048684f644d87521e5ca477b598831eb81e21", 
        Hash::calculate(HashKind::SASHA, "qwerty")
    );
}
#[test]
fn sasha_long_hash_test() {
    assert_eq!(
        "d370806299e4294a701aaaf6b573b0e1eb34a44cda3a09148e22f4972557a7a1e8ade94b2482398ac63ac6e664e91155a1cba034ca9bd592d07b88aeea27f2406502945ff5837608871d10cfd0de932b094d94c9700b145d920378be4b385548b1a4425a1849068c4abf70145a8641d4648dd2fed2943d73", 
        Hash::calculate(HashKind::SASHA, &"qwert".repeat(100))
    );
}