Open fathonix opened 9 months ago
cc @iyxan23
sounds cool, but sounds a bit over-engineered if im gonna be honest. i don't really have the time to do things like this, so ig its up to you. se7-se7 aja sih if you want to explore things further.
I agree, I think I'm too fascinated by minimal binaries like BusyBox and Toybox lately haha. Is there any suggestion on which language to use btw? I'm thinking of C for the sake of minimalism but I wanna hear yours.
what else would I choose? rust ofc lol hehe
anyways, now that AI is rampant, I made it convert the weirdly incompatible md5.js to rust:
use std::num::Wrapping;
fn safe_add(x: u32, y: u32) -> u32 {
let lsw = (Wrapping(x) & Wrapping(0xFFFF)).0 + (Wrapping(y) & Wrapping(0xFFFF)).0;
let msw = (x >> 16) + (y >> 16) + (lsw >> 16);
(msw << 16) | (lsw & 0xFFFF)
}
fn rol(num: u32, cnt: u32) -> u32 {
(num << cnt) | (num >> (32 - cnt))
}
fn cmn(q: u32, a: u32, b: u32, x: u32, s: u32, t: u32) -> u32 {
safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)
}
fn ff(a: u32, b: u32, c: u32, d: u32, x: u32, s: u32, t: u32) -> u32 {
cmn((b & c) | ((!b) & d), a, b, x, s, t)
}
fn gg(a: u32, b: u32, c: u32, d: u32, x: u32, s: u32, t: u32) -> u32 {
cmn((b & d) | (c & (!d)), a, b, x, s, t)
}
fn hh(a: u32, b: u32, c: u32, d: u32, x: u32, s: u32, t: u32) -> u32 {
cmn(b ^ c ^ d, a, b, x, s, t)
}
fn ii(a: u32, b: u32, c: u32, d: u32, x: u32, s: u32, t: u32) -> u32 {
cmn(c ^ (b | (!d)), a, b, x, s, t)
}
fn core_md5(x: &[u32]) -> [u32; 4] {
let mut a: u32 = 1732584193;
let mut b: u32 = -271733879;
let mut c: u32 = -1732584194;
let mut d: u32 = 271733878;
for i in (0..x.len()).step_by(16) {
let olda = a;
let oldb = b;
let oldc = c;
let oldd = d;
a = ff(a, b, c, d, x[i + 0], 7, -680876936);
d = ff(d, a, b, c, x[i + 1], 12, -389564586);
c = ff(c, d, a, b, x[i + 2], 17, 606105819);
b = ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = ff(a, b, c, d, x[i + 4], 7, -176418897);
d = ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = ff(b, c, d, a, x[i + 7], 22, -45705983);
a = ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = ff(c, d, a, b, x[i + 10], 17, -42063);
b = ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = ff(d, a, b, c, x[i + 13], 12, -40341101);
c = ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = gg(a, b, c, d, x[i + 1], 5, -165796510);
d = gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = gg(c, d, a, b, x[i + 11], 14, 643717713);
b = gg(b, c, d, a, x[i + 0], 20, -373897302);
a = gg(a, b, c, d, x[i + 5], 5, -701558691);
d = gg(d, a, b, c, x[i + 10], 9, 38016083);
c = gg(c, d, a, b, x[i + 15], 14, -660478335);
b = gg(b, c, d, a, x[i + 4], 20, -405537848);
a = gg(a, b, c, d, x[i + 9], 5, 568446438);
d = gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = gg(c, d, a, b, x[i + 3], 14, -187363961);
b = gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = gg(d, a, b, c, x[i + 2], 9, -51403784);
c = gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = hh(a, b, c, d, x[i + 5], 4, -378558);
d = hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = hh(b, c, d, a, x[i + 14], 23, -35309556);
a = hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = hh(c, d, a, b, x[i + 7], 16, -155497632);
b = hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = hh(a, b, c, d, x[i + 13], 4, 681279174);
d = hh(d, a, b, c, x[i + 0], 11, -358537222);
c = hh(c, d, a, b, x[i + 3], 16, -722521979);
b = hh(b, c, d, a, x[i + 6], 23, 76029189);
a = hh(a, b, c, d, x[i + 9], 4, -640364487);
d = hh(d, a, b, c, x[i + 12], 11, -421815835);
c = hh(c, d, a, b, x[i + 15], 16, 530742520);
b = hh(b, c, d, a, x[i + 2], 23, -995338651);
a = ii(a, b, c, d, x[i + 0], 6, -198630844);
d = ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = ii(b, c, d, a, x[i + 5], 21, -57434055);
a = ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = ii(c, d, a, b, x[i + 10], 15, -1051523);
b = ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = ii(d, a, b, c, x[i + 15], 10, -30611744);
c = ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = ii(a, b, c, d, x[i + 4], 6, -145523070);
d = ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = ii(c, d, a, b, x[i + 2], 15, 718787259);
b = ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
}
[a, b, c, d]
}
fn binl2hex(binarray: &[u32]) -> String {
let hex_tab = "0123456789abcdef";
let mut result = String::new();
for i in 0..binarray.len() * 4 {
result.push(
hex_tab.chars()
.nth(((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) as usize)
.unwrap(),
);
result.push(
hex_tab.chars()
.nth(((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF) as usize)
.unwrap(),
);
}
result
}
fn str2binl(input: &str) -> Vec<u32> {
let nblk = (input.len() + 8) >> 6 + 1;
let mut blks = vec![0; nblk * 16];
for (i, &c) in input.as_bytes().iter().enumerate() {
blks[i >> 2] |= (c as u32) << ((i % 4) * 8);
}
let len_bits = (input.len() as u64) * 8;
blks[nblk * 16 - 2] = len_bits as u32;
blks
}
fn hex_md5(input: &str) -> String {
let bin_array = str2binl(input);
let result = binl2hex(&core_md5(&bin_array));
result
}
fn main() {
let input_str = "Hello, world!";
let md5_result = hex_md5(input_str);
println!("MD5 Hash: {}", md5_result);
}
Dunno if this'll work or not, just my 2 cents if you wanted to investigate further.
This project was intended to be written in a language with minimal dependency, but the first time we wrote this we didn't find a compatible MD5 implementation. So we relied on Node.js to run
md5.js
.Recently, I found a tiny JS runtime called QuickJS. It implements most of ES2020 (which is way more than we need) and only adds ~200KB when embedded into a C program. Would be nice to have a statically compiled, lightweight single executable that could run without any external dependency.