Merge pull request #57 from pinkiebell/shuffling/test_vectors

Closes #51
This commit is contained in:
Paul Hauner 2018-10-21 22:07:13 +11:00 committed by GitHub
commit bdb5c45e60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 173 additions and 8 deletions

View File

@ -5,3 +5,6 @@ authors = ["Paul Hauner <paul@paulhauner.com>"]
[dependencies]
hashing = { path = "../hashing" }
[dev-dependencies]
yaml-rust = "0.4.2"

View File

@ -25,9 +25,15 @@ pub fn shuffle<T>(
-> Result<Vec<T>, ShuffleErr>
{
let mut rng = ShuffleRng::new(seed);
if list.len() > rng.rand_max as usize {
return Err(ShuffleErr::ExceedsListLength);
}
if list.is_empty() {
return Ok(list);
}
for i in 0..(list.len() - 1) {
let n = list.len() - i;
let j = rng.rand_range(n as u32) as usize + i;
@ -39,17 +45,40 @@ pub fn shuffle<T>(
#[cfg(test)]
mod tests {
extern crate yaml_rust;
use super::*;
use super::hashing::canonical_hash;
use std::fs::File;
use std::io::prelude::*;
use self::yaml_rust::yaml;
#[test]
fn test_shuffling() {
let seed = canonical_hash(b"4kn4driuctg8");
let list: Vec<usize> = (0..12).collect();
let s = shuffle(&seed, list).unwrap();
assert_eq!(
s,
vec![7, 3, 2, 5, 11, 9, 1, 0, 4, 6, 10, 8],
)
let mut file = File::open("./src/specs/shuffle_test_vectors.yaml").unwrap();
let mut yaml_str = String::new();
file.read_to_string(&mut yaml_str).unwrap();
let docs = yaml::YamlLoader::load_from_str(&yaml_str).unwrap();
let doc = &docs[0];
let test_cases = doc["test_cases"].as_vec();
for test_case in test_cases.unwrap() {
let input = test_case["input"].clone().into_vec().unwrap();
let output = test_case["output"].clone().into_vec().unwrap();
let seed_bytes = test_case["seed"].as_str().unwrap().as_bytes();
let mut seed;
if seed_bytes.len() > 0 {
seed = canonical_hash(seed_bytes);
} else {
seed = vec![];
}
let mut s = shuffle(&seed, input).unwrap();
assert_eq!(s, output);
}
}
}

View File

@ -2,7 +2,7 @@ use super::hashing::canonical_hash;
const SEED_SIZE_BYTES: usize = 32;
const RAND_BYTES: usize = 3; // 24 / 8
const RAND_MAX: u32 = 16_777_216; // 2**24
const RAND_MAX: u32 = 16_777_215; // 2 ** (rand_bytes * 8) - 1
/// A pseudo-random number generator which given a seed
/// uses successive blake2s hashing to generate "entropy".

View File

@ -0,0 +1,133 @@
# This file was generated with sigp/shuffling_sandbox
# python3 sandbox.py test_vectors
title: Shuffling Algorithm Tests
summary: Test vectors for shuffling a list based upon a seed.
test_suite: Shuffling
test_cases:
- input: []
output: []
seed: ''
- input: [0]
output: [0]
seed: ''
- input: [255]
output: [255]
seed: ''
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [1, 6, 4, 1, 6, 6, 2, 2, 4, 5]
seed: ''
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [4, 7, 10, 13, 3, 1, 2, 9, 12, 6, 11, 8, 5]
seed: ''
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [1, 6, 65, 1, 6, 6, 2, 2, 4, 5]
seed: ''
- input: []
output: []
seed: 4kn4driuctg8
- input: [0]
output: [0]
seed: 4kn4driuctg8
- input: [255]
output: [255]
seed: 4kn4driuctg8
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 4, 2, 5, 4, 2, 6, 6, 1, 1]
seed: 4kn4driuctg8
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [13, 1, 9, 8, 3, 10, 6, 2, 5, 12, 11, 4, 7]
seed: 4kn4driuctg8
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 65, 2, 5, 4, 2, 6, 6, 1, 1]
seed: 4kn4driuctg8
- input: []
output: []
seed: ytre1p
- input: [0]
output: [0]
seed: ytre1p
- input: [255]
output: [255]
seed: ytre1p
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 2, 5, 1, 6, 4, 1, 2, 4, 6]
seed: ytre1p
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [3, 8, 10, 4, 7, 11, 6, 1, 2, 5, 13, 9, 12]
seed: ytre1p
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 2, 5, 1, 6, 4, 1, 2, 65, 6]
seed: ytre1p
- input: []
output: []
seed: mytobcffnkvj
- input: [0]
output: [0]
seed: mytobcffnkvj
- input: [255]
output: [255]
seed: mytobcffnkvj
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [5, 6, 2, 1, 6, 4, 6, 4, 1, 2]
seed: mytobcffnkvj
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [12, 4, 11, 6, 13, 10, 9, 2, 3, 7, 8, 1, 5]
seed: mytobcffnkvj
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [5, 6, 2, 1, 6, 65, 6, 4, 1, 2]
seed: mytobcffnkvj
- input: []
output: []
seed: myzu3g7evxp5nkvj
- input: [0]
output: [0]
seed: myzu3g7evxp5nkvj
- input: [255]
output: [255]
seed: myzu3g7evxp5nkvj
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 2, 6, 5, 4, 4, 1, 6, 2, 1]
seed: myzu3g7evxp5nkvj
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [10, 12, 13, 3, 7, 11, 2, 4, 9, 8, 6, 5, 1]
seed: myzu3g7evxp5nkvj
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 2, 6, 5, 65, 4, 1, 6, 2, 1]
seed: myzu3g7evxp5nkvj
- input: []
output: []
seed: xdpli1jsx5xb
- input: [0]
output: [0]
seed: xdpli1jsx5xb
- input: [255]
output: [255]
seed: xdpli1jsx5xb
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 2, 4, 1, 2, 6, 5, 1, 6, 4]
seed: xdpli1jsx5xb
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [11, 8, 12, 9, 2, 1, 10, 4, 13, 5, 7, 3, 6]
seed: xdpli1jsx5xb
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 2, 65, 1, 2, 6, 5, 1, 6, 4]
seed: xdpli1jsx5xb
- input: []
output: []
seed: oab3mbb3xe8qsx5xb
- input: [0]
output: [0]
seed: oab3mbb3xe8qsx5xb
- input: [255]
output: [255]
seed: oab3mbb3xe8qsx5xb
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [2, 5, 1, 6, 1, 2, 6, 6, 4, 4]
seed: oab3mbb3xe8qsx5xb
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [5, 13, 9, 7, 11, 10, 12, 2, 6, 8, 3, 1, 4]
seed: oab3mbb3xe8qsx5xb
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [2, 5, 1, 6, 1, 2, 6, 6, 65, 4]
seed: oab3mbb3xe8qsx5xb