base64 encode id

This commit is contained in:
cool-mist
2026-01-17 00:31:49 +05:30
parent bce815d477
commit b15fb61c9e
4 changed files with 68 additions and 10 deletions
+2 -2
View File
@@ -29,7 +29,7 @@ fn main() {
let board = if let Some(board_string) = args.solve_board {
Board::from_string(board_string)
} else if let Some(board_id) = args.solve {
Board::from_id(board_id)
Board::from_id(&board_id)
} else {
println!("Use --help to see available options");
return;
@@ -106,7 +106,7 @@ struct Args {
#[argh(option, short = 's')]
/// the id of the board to solve
solve: Option<u128>,
solve: Option<String>,
#[argh(option)]
/// the board to solve in board representation
+21 -8
View File
@@ -17,6 +17,8 @@ use errors::SError;
use piece::Piece;
use square::{Square, SquarePair};
use crate::util;
#[derive(Clone)]
pub struct Board {
pub cells: [[Option<Piece>; BOARD_SIZE]; BOARD_SIZE],
@@ -43,12 +45,20 @@ impl Board {
}
}
pub fn from_id(board_id: u128) -> Result<Self, SError> {
pub fn from_id(board_id: &str) -> Result<Self, SError> {
let mut board_id_bytes = [0; 8];
board_id_bytes.copy_from_slice(board_id.as_bytes());
let mut working_bytes_slice = [0; 6];
util::b64_decode_48(&board_id_bytes, &mut working_bytes_slice);
let mut working_bytes = [0; 8];
working_bytes[2..].copy_from_slice(&working_bytes_slice);
let mut working = u64::from_be_bytes(working_bytes);
let mut board = Board::new();
let mut working = board_id;
let mask = 0b111;
for i in (0..BOARD_SIZE).rev() {
for j in (0..BOARD_SIZE).rev() {
let mask = 0b111;
let piece = Board::get_piece_from_encoding((working & mask) as u8);
working = working >> 3;
let piece = piece?;
@@ -136,21 +146,24 @@ impl Board {
pub fn pretty_print(&self) {
println!("{}", self.print(true));
// println!("{:^40}\n", format!("id: {:#018x}", self.id()));
println!("{:^40}\n", format!("id: {}", self.id()));
}
pub fn id(&self) -> u128 {
let mut res: u128 = 0;
pub fn id(&self) -> String {
let mut res: u64 = 0;
for i in 0..BOARD_SIZE {
for j in 0..BOARD_SIZE {
res = res << 3;
let byte = Board::get_piece_encoding(self.cells[i][j]);
res = res | byte as u128
res = res | byte as u64
}
}
res
let mut id_bytes = [0; 6];
id_bytes.copy_from_slice(&res.to_be_bytes()[2..]);
util::b64_encode_48(&id_bytes)
}
fn print(&self, pretty: bool) -> String {
@@ -585,7 +598,7 @@ mod tests {
board.set(sq!("Nc4"));
let id = board.id();
let board2 = Board::from_id(id);
let board2 = Board::from_id(&id);
let board2 = board2.unwrap();
validate_board!(board2, "..NB", "....", "RQ.K", "P...");
+1
View File
@@ -1,3 +1,4 @@
pub mod board;
pub mod generator;
pub mod solver;
pub mod util;
+44
View File
@@ -0,0 +1,44 @@
pub(crate) fn b64_encode_48(input: &[u8; 6]) -> String {
let mut output = [0 as char; 8];
for (byte_chunk, output_slice) in input.chunks_exact(3).zip(output.chunks_exact_mut(4)) {
let byte1 = byte_chunk[0];
let byte2 = byte_chunk[1];
let byte3 = byte_chunk[2];
output_slice[0] = lookup((byte1 & 0b1111_1100) >> 2);
output_slice[1] = lookup((byte1 & 0b0000_0011) << 4 | (byte2 & 0b1111_0000) >> 4);
output_slice[2] = lookup((byte2 & 0b0000_1111) << 2 | (byte3 & 0b1100_0000) >> 6);
output_slice[3] = lookup(byte3 & 0b0011_1111);
}
output.iter().collect()
}
pub(crate) fn b64_decode_48(input: &[u8; 8], output: &mut [u8; 6]) {
for (char_chunk, output_slice) in input.chunks_exact(4).zip(output.chunks_exact_mut(3)) {
let char_1 = reverse_lookup(char_chunk[0] as char);
let char_2 = reverse_lookup(char_chunk[1] as char);
let char_3 = reverse_lookup(char_chunk[2] as char);
let char_4 = reverse_lookup(char_chunk[3] as char);
output_slice[0] = (char_1 << 2) | (char_2 >> 4);
output_slice[1] = (char_2 << 4) | (char_3 >> 2);
output_slice[2] = (char_3 << 6) | char_4;
}
}
const ALPHABET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
fn lookup(idx: u8) -> char {
ALPHABET
.chars()
.nth(idx as usize)
.unwrap()
}
fn reverse_lookup(c: char) -> u8 {
ALPHABET
.chars()
.position(|x| x == c)
.unwrap() as u8
}