2019-09-08 17:45:51 +03:00
|
|
|
import bitfield
|
2019-07-09 22:11:09 +03:00
|
|
|
|
|
|
|
import rand
|
2019-07-13 19:17:45 +03:00
|
|
|
import time
|
2019-07-09 22:11:09 +03:00
|
|
|
|
|
|
|
fn test_bf_new_size() {
|
2019-09-08 17:55:27 +03:00
|
|
|
instance := bitfield.new(75)
|
2019-07-12 21:46:37 +03:00
|
|
|
assert instance.getsize() == 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)
|
2019-07-12 21:46:37 +03:00
|
|
|
instance.setbit(47)
|
|
|
|
assert instance.getbit(47) == 1
|
|
|
|
instance.clearbit(47)
|
|
|
|
assert instance.getbit(47) == 0
|
|
|
|
instance.togglebit(47)
|
|
|
|
assert instance.getbit(47) == 1
|
2019-07-09 22:11:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_and_not_or_xor() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-09 22:11:09 +03:00
|
|
|
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 {
|
|
|
|
if rand.next(2) == 1 {
|
|
|
|
input1.setbit(i)
|
|
|
|
}
|
|
|
|
if rand.next(2) == 1{
|
|
|
|
input2.setbit(i)
|
|
|
|
}
|
|
|
|
i++
|
|
|
|
}
|
2019-09-08 17:55:27 +03:00
|
|
|
output1 := bitfield.bfxor(input1, input2)
|
|
|
|
bfand := bitfield.bfand(input1, input2)
|
|
|
|
bfor := bitfield.bfor(input1, input2)
|
|
|
|
bfnot := bitfield.bfnot(bfand)
|
|
|
|
output2 := bitfield.bfand(bfor, bfnot)
|
2019-07-09 22:11:09 +03:00
|
|
|
mut result := 1
|
|
|
|
for i < len {
|
|
|
|
if output1.getbit(i) != output2.getbit(i) {result = 0}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
2019-07-12 21:46:37 +03:00
|
|
|
|
|
|
|
fn test_clone_cmp() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-12 21:46:37 +03:00
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-12 21:46:37 +03:00
|
|
|
if rand.next(2) == 1 {
|
|
|
|
input.setbit(i)
|
|
|
|
}
|
|
|
|
}
|
2020-04-04 18:59:26 +03:00
|
|
|
output := input.clone()
|
2019-07-12 21:46:37 +03:00
|
|
|
assert output.getsize() == len
|
2020-04-04 18:59:26 +03:00
|
|
|
assert input.cmp(output) == true
|
2019-07-12 21:46:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn test_slice_join() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-12 21:46:37 +03:00
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-12 21:46:37 +03:00
|
|
|
if rand.next(2) == 1 {
|
|
|
|
input.setbit(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mut result := 1
|
|
|
|
for point := 1; point < (len - 1); point++ {
|
|
|
|
// divide a bitfield into two subfields
|
|
|
|
chunk1 := input.slice(0, point)
|
|
|
|
chunk2 := input.slice(point, input.getsize())
|
|
|
|
// concatenate them back into one and compare to the original
|
2019-09-08 17:55:27 +03:00
|
|
|
output := bitfield.join(chunk1, chunk2)
|
2020-04-04 18:59:26 +03:00
|
|
|
if !input.cmp(output) {
|
2019-07-12 21:46:37 +03:00
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_popcount() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
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-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-12 21:46:37 +03:00
|
|
|
if rand.next(2) == 1 {
|
|
|
|
input.setbit(i)
|
|
|
|
count0++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
count1 := input.popcount()
|
|
|
|
assert count0 == count1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_hamming() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-12 21:46:37 +03:00
|
|
|
len := 80
|
|
|
|
mut count := 0
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input1 := bitfield.new(len)
|
|
|
|
mut input2 := bitfield.new(len)
|
2020-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-10-27 13:03:40 +03:00
|
|
|
match rand.next(4) {
|
|
|
|
0, 1 {
|
2019-07-12 21:46:37 +03:00
|
|
|
input1.setbit(i)
|
|
|
|
count++
|
2019-10-27 13:03:40 +03:00
|
|
|
}
|
|
|
|
2 {
|
2019-07-12 21:46:37 +03:00
|
|
|
input2.setbit(i)
|
|
|
|
count++
|
2019-10-27 13:03:40 +03:00
|
|
|
}
|
|
|
|
3 {
|
2019-07-12 21:46:37 +03:00
|
|
|
input1.setbit(i)
|
|
|
|
input2.setbit(i)
|
2019-10-27 13:03:40 +03:00
|
|
|
}
|
2019-12-07 17:13:25 +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() {
|
|
|
|
input := [byte(0xF0), byte(0x0F), byte(0xF0), byte(0xFF)]
|
|
|
|
output := bitfield.from_bytes(input)
|
|
|
|
mut result := 1
|
2020-02-24 19:55:16 +03:00
|
|
|
for i in 0..input.len * 8 {
|
2019-11-19 03:32:44 +03:00
|
|
|
if (input[i / 8] >> (i % 8)) & 1 != output.getbit(i) {
|
2019-11-13 19:48:00 +03:00
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
2020-04-04 18:59:26 +03:00
|
|
|
fn test_bf_from_str() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-14 18:56:48 +03:00
|
|
|
len := 80
|
|
|
|
mut input := ''
|
2020-04-27 23:53:26 +03:00
|
|
|
for _ in 0..len {
|
2019-07-14 18:56:48 +03:00
|
|
|
if rand.next(2) == 1 {
|
|
|
|
input = input + '1'
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
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-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-14 18:56:48 +03:00
|
|
|
if input[i] != output.getbit(i) + 48 {
|
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_bf2str() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-14 18:56:48 +03:00
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-14 18:56:48 +03:00
|
|
|
if rand.next(2) == 1 {
|
|
|
|
input.setbit(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mut check := ''
|
2020-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-14 18:56:48 +03:00
|
|
|
if input.getbit(i) == 1 {
|
|
|
|
check = check + '1'
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
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-02-24 19:55:16 +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
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_setall() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-14 18:56:48 +03:00
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2019-07-14 18:56:48 +03:00
|
|
|
input.setall()
|
|
|
|
mut result := 1
|
2020-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-14 18:56:48 +03:00
|
|
|
if input.getbit(i) != 1 {
|
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_clearall() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-14 18:56:48 +03:00
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-14 18:56:48 +03:00
|
|
|
if rand.next(2) == 1 {
|
|
|
|
input.setbit(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
input.clearall()
|
|
|
|
mut result := 1
|
2020-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-14 18:56:48 +03:00
|
|
|
if input.getbit(i) != 0 {
|
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
2019-07-15 20:07:07 +03:00
|
|
|
|
|
|
|
fn test_bf_reverse() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-15 20:07:07 +03:00
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(len)
|
2020-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-15 20:07:07 +03:00
|
|
|
if rand.next(2) == 1 {
|
|
|
|
input.setbit(i)
|
|
|
|
}
|
|
|
|
}
|
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-02-24 19:55:16 +03:00
|
|
|
for i in 0..len {
|
2019-07-15 20:07:07 +03:00
|
|
|
if output.getbit(i) != check.getbit(len - i - 1) {
|
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_resize() {
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-15 20:07:07 +03:00
|
|
|
len := 80
|
2019-09-08 17:55:27 +03:00
|
|
|
mut input := bitfield.new(rand.next(len) + 1)
|
2020-04-27 23:53:26 +03:00
|
|
|
for _ in 0..100 {
|
2019-07-29 11:37:39 +03:00
|
|
|
input.resize(rand.next(len) + 1)
|
2019-07-15 20:07:07 +03:00
|
|
|
input.setbit(input.getsize() - 1)
|
|
|
|
}
|
|
|
|
assert input.getbit(input.getsize() - 1) == 1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_bf_pos() {
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
**/
|
2019-12-31 19:11:47 +03:00
|
|
|
rand.seed(time.now().unix)
|
2019-07-15 20:07:07 +03:00
|
|
|
len := 80
|
|
|
|
mut result := 1
|
|
|
|
for i := 1; i < len; i++ { // needle size
|
2020-02-24 19:55:16 +03:00
|
|
|
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-02-24 19:55:16 +03:00
|
|
|
for k in 0..i {
|
2019-07-15 20:07:07 +03:00
|
|
|
if rand.next(2) == 1 {
|
|
|
|
needle.setbit(k)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// make sure the needle contains at least one set bit, selected randomly
|
|
|
|
r := rand.next(i)
|
|
|
|
needle.setbit(r)
|
|
|
|
|
|
|
|
// 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)
|
2019-07-15 20:07:07 +03:00
|
|
|
chunk1.setall()
|
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)
|
|
|
|
if output.getbit(len - i - 1) != 0 || output.getbit(len - i) != 1 {
|
|
|
|
result = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert result == 1
|
|
|
|
}
|
2020-04-04 18:03:03 +03:00
|
|
|
|
|
|
|
fn test_bf_printing(){
|
|
|
|
rand.seed(time.now().unix)
|
|
|
|
len := 80
|
|
|
|
mut input := bitfield.new(len)
|
|
|
|
for i in 0..len {
|
|
|
|
if rand.next(2) == 0 {
|
|
|
|
input.setbit(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// the following should convert the bitfield input into a string automatically
|
|
|
|
println(input)
|
|
|
|
assert true
|
|
|
|
}
|