Skip to content

Instantly share code, notes, and snippets.

@lovasoa
Last active June 19, 2024 22:47
Show Gist options
  • Save lovasoa/9bb6c50feed7bb264c15ae65c6222b45 to your computer and use it in GitHub Desktop.
Save lovasoa/9bb6c50feed7bb264c15ae65c6222b45 to your computer and use it in GitHub Desktop.
[package]
name = "hash_miner"
version = "0.1.0"
edition = "2021"
[dependencies]
rayon = "1.5"
sha2 = "0.10"
num_cpus = "1.13"
[profile.release]
opt-level = 3
debug = false
lto = true
[target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))']
rustflags = ["-C", "target-cpu=native"]
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
use sha2::{Sha256, Digest};
use rayon::iter::IntoParallelIterator;
use rayon::iter::ParallelIterator;
const PREFIX: &[u8] = b"x/https+ophir+dev/";
const BLOCK_SIZE: usize = 32; // SHA256 hash size in bytes
const CHAR_START: u8 = b'a';
const CHAR_END: u8 = b'z';
/// Function to find the string with the lowest hash (most leading zeroes)
fn find_lowest_hash(num_threads: usize) {
let max_zeroes = Arc::new(AtomicU32::new(0));
(0..num_threads).into_par_iter().for_each(|thread_idx| {
let mut candidate = [CHAR_START; BLOCK_SIZE];
candidate[..PREFIX.len()].copy_from_slice(PREFIX);
candidate[PREFIX.len()] = CHAR_START + thread_idx as u8;
let mut hasher = Sha256::new();
loop {
increment_bytes(&mut candidate);
// Compute the SHA256 hash
hasher.update(&candidate);
let leading_zeroes = count_leading_zeroes(&hasher.finalize_reset());
// Update maximum leading zeroes found
let current_max = max_zeroes.load(Ordering::Relaxed);
if leading_zeroes > current_max {
max_zeroes.store(leading_zeroes, Ordering::Relaxed);
println!("New best string: {} with leading zeroes: {}", String::from_utf8_lossy(&candidate), leading_zeroes);
}
}
});
}
/// Increments the given byte array by one, wrapping within CHAR_START..CHAR_END
fn increment_bytes(arr: &mut [u8; BLOCK_SIZE]) {
for byte in arr.iter_mut().rev() {
if *byte == CHAR_END {
*byte = CHAR_START;
} else {
*byte += 1;
return; // No need to carry over to higher digits
}
}
}
/// Counts the number of leading zeroes in a hexadecimal string
fn count_leading_zeroes(hash: &[u8]) -> u32 {
let mut leading_zeroes = 0;
// Count full bytes of leading zeroes
for &byte in hash {
let zeros = byte.leading_zeros();
leading_zeroes += zeros;
if zeros < 8 {
break;
}
}
leading_zeroes
}
fn main() {
let num_threads = num_cpus::get();
find_lowest_hash(num_threads);
}
RUSTFLAGS="-C target-cpu=native" cargo run --release
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment