Skip to content

Instantly share code, notes, and snippets.

@YanWQ-monad
Last active March 15, 2023 09:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YanWQ-monad/4febc8f8635514459a981adfefb1b9f1 to your computer and use it in GitHub Desktop.
Save YanWQ-monad/4febc8f8635514459a981adfefb1b9f1 to your computer and use it in GitHub Desktop.
Hackergame 2021 赛博厨房 Level 2, code snippets
#![feature(test)]
extern crate test;
mod random;
use sha2::{Digest, Sha256};
use random::Random;
fn check(seed: &str) -> bool {
assert_eq!(seed.len(), 64);
let mut random = Random::new(&seed);
for _ in 0..5 {
if random.next_u32() % 32 != 0 {
return false
}
}
true
}
fn main() {
let mut init_hasher = Sha256::new();
for i in 1..=32 {
let mut hasher = Sha256::new();
hasher.update("向右 1 步\n拿起 5 个物品\n向左 1 步\n放下 1 个物品\n放下 1 个物品\n放下 1 个物品\n放下 1 个物品\n放下 1 个物品\n".as_bytes());
hasher.update(format!("向右 {} 步\n拿起 1 个物品\n向左 {} 步\n放下 1 个物品", i, i).as_bytes());
let result = format!("{:32x}\n", hasher.finalize());
init_hasher.update(result.as_bytes());
}
let mut i = 0;
loop {
if i % 100000 == 0 {
println!("{:?}", i);
}
let mut hasher = Sha256::new();
hasher.update(format!("向右 {} 步", i).as_bytes());
let result = format!("{:32x}", hasher.finalize());
let mut hasher = init_hasher.clone();
hasher.update(result.as_bytes());
let result = format!("{:32x}", hasher.finalize());
if check(&result) {
println!("{:?}", i);
break;
}
i += 1;
}
}
use std::cmp::min;
pub struct Random {
s: [u8; 256],
i: u8,
j: u8,
}
impl Random {
pub fn new(seed: &str) -> Random {
let key_length = min(seed.len(), 256);
let mut key = vec![0u8; key_length];
mixkey(seed, &mut key);
let mut s = [0u8; 256];
for i in 0..=255 {
s[i as usize] = i;
}
let mut j = 0u8;
for i in 0..=255 {
j = j.wrapping_add(key[i % key_length]).wrapping_add(s[i]);
s.swap(i, j as usize);
}
let mut random = Random { s, i: 0, j: 0 };
random.gen(256);
random
}
pub fn next_u32(&mut self) -> u32 {
self.gen(4)
}
pub fn gen(&mut self, count: usize) -> u32 {
let mut r = 0u32;
for _ in 0..count {
self.i = self.i.wrapping_add(1);
let t = self.s[self.i as usize];
self.j = self.j.wrapping_add(t);
self.s.swap(self.i as usize, self.j as usize);
r = r.wrapping_mul(256).wrapping_add(
self.s[u8::wrapping_add(self.s[self.i as usize], self.s[self.j as usize]) as usize]
as u32,
);
}
r
}
}
fn mixkey(seed: &str, key: &mut [u8]) {
let mut smear: u8 = 0;
for (i, c) in seed.chars().enumerate() {
smear ^= key[i & 0xFF] * 19;
key[i & 0xFF] = smear + (c as u8);
}
}
#[cfg(test)]
mod tests {
use super::*;
use test::Bencher;
#[test]
fn test_random() {
let mut random =
Random::new("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ54778#$%6726");
assert_eq!(random.next_u32(), 1745535624);
assert_eq!(random.next_u32(), 3663789844);
assert_eq!(random.next_u32(), 3295663675);
let mut random = Random::new("abcdefghijklmnopqJKLMNOPQRSTUVWXYZ54778#$%6726");
assert_eq!(random.next_u32(), 623630346);
}
#[bench]
fn bench_random(b: &mut Bencher) {
let mut random =
Random::new("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ54778#$%6726");
b.iter(|| random.next_u32());
}
#[bench]
fn bench_gen(b: &mut Bencher) {
b.iter(|| Random::new("abcdefghijklmnopqr658932yzABCDEFGHIJKLMNOPQRSTUVWXYZ54778#$%6726"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment