2019-09-08 17:45:51 +03:00
|
|
|
import bitfield
|
2019-07-09 22:11:09 +03:00
|
|
|
import rand
|
|
|
|
|
|
|
|
fn test_bf_new_size() {
|
2019-09-08 17:55:27 +03:00
|
|
|
instance := bitfield.new(75)
|
2020-05-07 11:21:14 +03:00
|
|
|
assert instance.get_size() == 75
|
2019-07-09 22:11:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_set_clear_toggle_get() {
|
2019-09-08 17:55:27 +03:00
|
|
|
mut instance := bitfield.new(75)
|
2020-05-07 11:21:14 +03:00
|
|
|
instance.set_bit(47)
|
|
|
|
assert instance.get_bit(47) == 1
|
|
|
|
instance.clear_bit(47)
|
|
|
|
assert instance.get_bit(47) == 0
|
|
|
|
instance.toggle_bit(47)
|
|
|
|
assert instance.get_bit(47) == 1
|
2019-07-09 22:11:09 +03:00
|
|
|
}
|
|
|
|
|
2021-04-10 17:42:09 +03:00
|
|
|
fn test_bf_insert_extract() {
|
|
|
|
mut instance := bitfield.new(11)
|
|
|
|
instance.set_all()
|
|
|
|
instance.insert(2, 9, 3)
|
|
|
|
assert instance.extract(2, 1) == 0
|
|
|
|
assert instance.extract(2, 8) == 1
|
|
|
|
assert instance.extract(10, 1) == 1
|
|
|
|
instance.set_all()
|
|
|
|
instance.insert_lowest_bits_first(2, 9, 3)
|
|
|
|
assert instance.extract_lowest_bits_first(2, 1) == 1
|
|
|
|
assert instance.extract_lowest_bits_first(2, 8) == 3
|
|
|
|
assert instance.extract_lowest_bits_first(10, 1) == 0
|
|
|
|
}
|
|
|
|
|
2019-07-09 22:11:09 +03:00
|
|
|
fn test_bf_and_not_or_xor() {
|
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input1 := bitfield.new(len)
|
|
|
|
mut input2 := bitfield.new(len)
|
2019-07-09 22:11:09 +03:00
|
|
|
mut i := 0
|
|
|
|
for i < len {
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 1 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input1.set_bit(i)
|
2019-07-09 22:11:09 +03:00
|
|
|
}
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 1 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input2.set_bit(i)
|
2019-07-09 22:11:09 +03:00
|
|
|
}
|
|
|
|
i++
|
|
|
|
}
|
2020-05-07 11:21:14 +03:00
|
|
|
output1 := bitfield.bf_xor(input1, input2)
|
|
|
|
bf_and := bitfield.bf_and(input1, input2)
|
|
|
|
bf_or := bitfield.bf_or(input1, input2)
|
|
|
|
bf_not := bitfield.bf_not(bf_and)
|
|
|
|
output2 := bitfield.bf_and(bf_or, bf_not)
|
2019-07-09 22:11:09 +03:00
|
|
|
mut result := 1
|
|
|
|
for i < len {
|
2020-12-18 22:47:24 +03:00
|
|
|
if output1.get_bit(i) != output2.get_bit(i) {
|
|
|
|
result = 0
|
|
|
|
}
|
2019-07-09 22:11:09 +03:00
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
2019-07-12 21:46:37 +03:00
|
|
|
|
|
|
|
fn test_clone_cmp() {
|
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 1 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input.set_bit(i)
|
2019-07-12 21:46:37 +03:00
|
|
|
}
|
|
|
|
}
|
2020-04-04 18:59:26 +03:00
|
|
|
output := input.clone()
|
2020-05-07 11:21:14 +03:00
|
|
|
assert output.get_size() == len
|
2021-06-24 07:27:04 +03:00
|
|
|
assert input == output
|
2019-07-12 21:46:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn test_slice_join() {
|
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 1 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input.set_bit(i)
|
2019-07-12 21:46:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
mut result := 1
|
|
|
|
for point := 1; point < (len - 1); point++ {
|
|
|
|
// divide a bitfield into two subfields
|
|
|
|
chunk1 := input.slice(0, point)
|
2020-05-07 11:21:14 +03:00
|
|
|
chunk2 := input.slice(point, input.get_size())
|
2019-07-12 21:46:37 +03:00
|
|
|
// concatenate them back into one and compare to the original
|
2019-09-08 17:55:27 +03:00
|
|
|
output := bitfield.join(chunk1, chunk2)
|
2021-06-24 07:27:04 +03:00
|
|
|
if input != output {
|
2019-07-12 21:46:37 +03:00
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
2020-05-07 11:21:14 +03:00
|
|
|
fn test_pop_count() {
|
2019-07-12 21:46:37 +03:00
|
|
|
len := 80
|
|
|
|
mut count0 := 0
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 1 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input.set_bit(i)
|
2019-07-12 21:46:37 +03:00
|
|
|
count0++
|
|
|
|
}
|
|
|
|
}
|
2020-05-07 11:21:14 +03:00
|
|
|
count1 := input.pop_count()
|
2019-07-12 21:46:37 +03:00
|
|
|
assert count0 == count1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_hamming() {
|
|
|
|
len := 80
|
|
|
|
mut count := 0
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input1 := bitfield.new(len)
|
|
|
|
mut input2 := bitfield.new(len)
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2022-02-23 13:36:14 +03:00
|
|
|
match rand.intn(4) or { 0 } {
|
2019-10-27 13:03:40 +03:00
|
|
|
0, 1 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input1.set_bit(i)
|
2019-07-12 21:46:37 +03:00
|
|
|
count++
|
2019-10-27 13:03:40 +03:00
|
|
|
}
|
|
|
|
2 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input2.set_bit(i)
|
2019-07-12 21:46:37 +03:00
|
|
|
count++
|
2019-10-27 13:03:40 +03:00
|
|
|
}
|
|
|
|
3 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input1.set_bit(i)
|
|
|
|
input2.set_bit(i)
|
2019-10-27 13:03:40 +03:00
|
|
|
}
|
2020-12-18 22:47:24 +03:00
|
|
|
else {}
|
2019-07-12 21:46:37 +03:00
|
|
|
}
|
|
|
|
}
|
2019-09-08 17:55:27 +03:00
|
|
|
assert count == bitfield.hamming(input1, input2)
|
2019-07-12 21:46:37 +03:00
|
|
|
}
|
2019-07-14 18:56:48 +03:00
|
|
|
|
2019-11-13 19:48:00 +03:00
|
|
|
fn test_bf_from_bytes() {
|
2020-12-18 22:47:24 +03:00
|
|
|
input := [byte(0x01), 0xF0, 0x0F, 0xF0, 0xFF]
|
|
|
|
output := bitfield.from_bytes(input).str()
|
|
|
|
assert output == '00000001' + '11110000' + '00001111' + '11110000' + '11111111'
|
|
|
|
newoutput := bitfield.from_str(output).str()
|
|
|
|
assert newoutput == output
|
2019-11-13 19:48:00 +03:00
|
|
|
}
|
|
|
|
|
2020-12-18 22:58:42 +03:00
|
|
|
fn test_bf_from_bytes_lowest_bits_first() {
|
|
|
|
input := [byte(0x01), 0xF0]
|
|
|
|
output := bitfield.from_bytes_lowest_bits_first(input).str()
|
|
|
|
assert output == '10000000' + '00001111'
|
|
|
|
newoutput := bitfield.from_str(output).str()
|
|
|
|
assert newoutput == output
|
|
|
|
}
|
|
|
|
|
2020-04-04 18:59:26 +03:00
|
|
|
fn test_bf_from_str() {
|
2019-07-14 18:56:48 +03:00
|
|
|
len := 80
|
|
|
|
mut input := ''
|
2020-12-18 22:47:24 +03:00
|
|
|
for _ in 0 .. len {
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 1 {
|
2019-07-14 18:56:48 +03:00
|
|
|
input = input + '1'
|
2020-12-18 22:47:24 +03:00
|
|
|
} else {
|
2019-07-14 18:56:48 +03:00
|
|
|
input = input + '0'
|
|
|
|
}
|
|
|
|
}
|
2020-04-04 18:59:26 +03:00
|
|
|
output := bitfield.from_str(input)
|
2019-07-14 18:56:48 +03:00
|
|
|
mut result := 1
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2020-05-07 11:21:14 +03:00
|
|
|
if input[i] != output.get_bit(i) + 48 {
|
2019-07-14 18:56:48 +03:00
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_bf2str() {
|
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 1 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input.set_bit(i)
|
2019-07-14 18:56:48 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
mut check := ''
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2020-05-07 11:21:14 +03:00
|
|
|
if input.get_bit(i) == 1 {
|
2019-07-14 18:56:48 +03:00
|
|
|
check = check + '1'
|
2020-12-18 22:47:24 +03:00
|
|
|
} else {
|
2019-07-14 18:56:48 +03:00
|
|
|
check = check + '0'
|
|
|
|
}
|
|
|
|
}
|
2020-04-04 18:03:03 +03:00
|
|
|
output := input.str()
|
2019-07-14 18:56:48 +03:00
|
|
|
mut result := 1
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2019-07-14 18:56:48 +03:00
|
|
|
if check[i] != output[i] {
|
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
2020-05-07 11:21:14 +03:00
|
|
|
fn test_bf_set_all() {
|
2019-07-14 18:56:48 +03:00
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-05-07 11:21:14 +03:00
|
|
|
input.set_all()
|
2019-07-14 18:56:48 +03:00
|
|
|
mut result := 1
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2020-05-07 11:21:14 +03:00
|
|
|
if input.get_bit(i) != 1 {
|
2019-07-14 18:56:48 +03:00
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
2020-05-07 11:21:14 +03:00
|
|
|
fn test_bf_clear_all() {
|
2019-07-14 18:56:48 +03:00
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 1 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input.set_bit(i)
|
2019-07-14 18:56:48 +03:00
|
|
|
}
|
|
|
|
}
|
2020-05-07 11:21:14 +03:00
|
|
|
input.clear_all()
|
2019-07-14 18:56:48 +03:00
|
|
|
mut result := 1
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2020-05-07 11:21:14 +03:00
|
|
|
if input.get_bit(i) != 0 {
|
2019-07-14 18:56:48 +03:00
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
2019-07-15 20:07:07 +03:00
|
|
|
|
|
|
|
fn test_bf_reverse() {
|
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 1 {
|
2020-05-07 11:21:14 +03:00
|
|
|
input.set_bit(i)
|
2019-07-15 20:07:07 +03:00
|
|
|
}
|
|
|
|
}
|
2020-04-04 18:59:26 +03:00
|
|
|
check := input.clone()
|
2019-07-15 20:07:07 +03:00
|
|
|
output := input.reverse()
|
|
|
|
mut result := 1
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2020-05-07 11:21:14 +03:00
|
|
|
if output.get_bit(i) != check.get_bit(len - i - 1) {
|
2019-07-15 20:07:07 +03:00
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_resize() {
|
|
|
|
len := 80
|
2022-02-23 13:36:14 +03:00
|
|
|
mut input := bitfield.new(rand.intn(len) or { 0 } + 1)
|
2020-12-18 22:47:24 +03:00
|
|
|
for _ in 0 .. 100 {
|
2022-02-23 13:36:14 +03:00
|
|
|
input.resize(rand.intn(len) or { 0 } + 1)
|
2020-05-07 11:21:14 +03:00
|
|
|
input.set_bit(input.get_size() - 1)
|
2019-07-15 20:07:07 +03:00
|
|
|
}
|
2020-05-07 11:21:14 +03:00
|
|
|
assert input.get_bit(input.get_size() - 1) == 1
|
2019-07-15 20:07:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_pos() {
|
2020-12-18 22:47:24 +03:00
|
|
|
/*
|
|
|
|
*
|
2019-07-15 20:07:07 +03:00
|
|
|
* set haystack size to 80
|
|
|
|
* test different sizes of needle, from 1 to 80
|
|
|
|
* test different positions of needle, from 0 to where it fits
|
|
|
|
* all haystacks here contain exactly one instanse of needle,
|
|
|
|
* so search should return non-negative-values
|
2020-12-18 22:47:24 +03:00
|
|
|
*
|
|
|
|
*/
|
2019-07-15 20:07:07 +03:00
|
|
|
len := 80
|
|
|
|
mut result := 1
|
2020-12-18 22:47:24 +03:00
|
|
|
for i := 1; i < len; i++ { // needle size
|
|
|
|
for j in 0 .. len - i { // needle position in the haystack
|
2019-07-15 20:07:07 +03:00
|
|
|
// create the needle
|
2019-09-08 17:55:27 +03:00
|
|
|
mut needle := bitfield.new(i)
|
2019-07-15 20:07:07 +03:00
|
|
|
// fill the needle with random values
|
2020-12-18 22:47:24 +03:00
|
|
|
for k in 0 .. i {
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 1 {
|
2020-05-07 11:21:14 +03:00
|
|
|
needle.set_bit(k)
|
2019-07-15 20:07:07 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// make sure the needle contains at least one set bit, selected randomly
|
2022-02-23 13:36:14 +03:00
|
|
|
r := rand.intn(i) or { 0 }
|
2020-05-07 11:21:14 +03:00
|
|
|
needle.set_bit(r)
|
2019-07-15 20:07:07 +03:00
|
|
|
// create the haystack, make sure it contains the needle
|
2020-04-04 18:59:26 +03:00
|
|
|
mut haystack := needle.clone()
|
2019-07-15 20:07:07 +03:00
|
|
|
// if there is space between the start of the haystack and the sought needle, fill it with zeroes
|
|
|
|
if j > 0 {
|
2019-09-08 17:55:27 +03:00
|
|
|
start := bitfield.new(j)
|
|
|
|
tmp := bitfield.join(start, haystack)
|
2019-07-15 20:07:07 +03:00
|
|
|
haystack = tmp
|
|
|
|
}
|
|
|
|
// if there is space between the sought needle and the end of haystack, fill it with zeroes
|
|
|
|
if j + i < len {
|
2019-09-08 17:55:27 +03:00
|
|
|
end := bitfield.new(len - j - i)
|
|
|
|
tmp2 := bitfield.join(haystack, end)
|
2019-07-15 20:07:07 +03:00
|
|
|
haystack = tmp2
|
|
|
|
}
|
|
|
|
// now let's test
|
|
|
|
// the result should be equal to j
|
|
|
|
if haystack.pos(needle) != j {
|
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_rotate() {
|
|
|
|
mut result := 1
|
|
|
|
len := 80
|
|
|
|
for i := 1; i < 80 && result == 1; i++ {
|
2019-09-08 17:55:27 +03:00
|
|
|
mut chunk1 := bitfield.new(i)
|
|
|
|
chunk2 := bitfield.new(len - i)
|
2020-05-07 11:21:14 +03:00
|
|
|
chunk1.set_all()
|
2019-09-08 17:55:27 +03:00
|
|
|
input := bitfield.join(chunk1, chunk2)
|
2019-07-15 20:07:07 +03:00
|
|
|
output := input.rotate(i)
|
2020-05-07 11:21:14 +03:00
|
|
|
if output.get_bit(len - i - 1) != 0 || output.get_bit(len - i) != 1 {
|
2019-07-15 20:07:07 +03:00
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
2020-04-04 18:03:03 +03:00
|
|
|
|
2020-12-18 22:47:24 +03:00
|
|
|
fn test_bf_printing() {
|
2020-04-04 18:03:03 +03:00
|
|
|
len := 80
|
|
|
|
mut input := bitfield.new(len)
|
2020-12-18 22:47:24 +03:00
|
|
|
for i in 0 .. len {
|
2022-02-23 13:36:14 +03:00
|
|
|
if rand.intn(2) or { 0 } == 0 {
|
2020-12-18 22:47:24 +03:00
|
|
|
input.set_bit(i)
|
|
|
|
}
|
2020-04-04 18:03:03 +03:00
|
|
|
}
|
|
|
|
// the following should convert the bitfield input into a string automatically
|
|
|
|
println(input)
|
|
|
|
assert true
|
|
|
|
}
|