Skip to content

Commit e06dc4b

Browse files
committed
fix issue #37, rework tests
1 parent 76a5013 commit e06dc4b

File tree

7 files changed

+69
-98
lines changed

7 files changed

+69
-98
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.eggs
12
*.egg-info/
23
.vscode/
34
__pycache__/
@@ -9,4 +10,4 @@ dist/
910
.pydevproject
1011
.pytest_cache
1112
.settings
12-
MANIFEST
13+
MANIFEST

src/bch.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,7 @@ struct gf_poly {
153153

154154
/* polynomial of degree 1 */
155155
struct gf_poly_deg1 {
156-
struct {
157-
unsigned int deg;
158-
} poly;
156+
struct gf_poly poly;
159157
unsigned int c[2];
160158
};
161159

@@ -993,7 +991,7 @@ static void factor_polynomial(struct bch_control *bch, int k, struct gf_poly *f,
993991
/* compute h=f/gcd(f,tk); this will modify f and q */
994992
gf_poly_div(bch, f, gcd, q);
995993
/* store g and h in-place (clobbering f) */
996-
*h = (struct gf_poly *) &((struct gf_poly_deg1 *)f)[gcd->deg].poly;
994+
*h = &((struct gf_poly_deg1 *)f)[gcd->deg].poly;
997995
gf_poly_copy(*g, gcd);
998996
gf_poly_copy(*h, q);
999997
}
@@ -1126,7 +1124,7 @@ int bch_decode(struct bch_control *bch, const uint8_t *data, unsigned int len,
11261124
uint32_t sum;
11271125

11281126
/* sanity check: make sure data length can be handled */
1129-
if (8*len-7 > (bch->n-bch->ecc_bits))
1127+
if (8*len > (bch->n-bch->ecc_bits))
11301128
return -EINVAL;
11311129

11321130
/* if caller does not provide syndromes, compute them */

tests/test_chaining.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import bchlib
44
import unittest
55

6-
class BCHTestCase(unittest.TestCase):
6+
class Tests(unittest.TestCase):
77
def test(self):
88
bch = bchlib.BCH(16, m=13)
99
ecc = bch.encode(b'First')

tests/test_consecutive.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import bchlib
44
import unittest
55

6-
class BCHTestCase(unittest.TestCase):
6+
class Tests(unittest.TestCase):
77
def test(self):
88
bch = bchlib.BCH(16, m=13)
99
ecc1 = bch.encode(b'First')

tests/test_exercise.py

Lines changed: 61 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,98 @@
11
#!/usr/bin/env python
22

3-
import binascii
4-
import hashlib
53
import os
64
import random
75
import unittest
86

97
import bchlib
108

119

12-
def bitflip(data, bits):
13-
bit = random.randint(8 - (bits % 8), bits)
14-
data[bit // 8] ^= 0x80 >> (bit % 8)
10+
def bitflip(data):
11+
bit = random.randint(0, len(data) * 8 - 1)
12+
data[bit // 8] ^= 1 << (bit % 8)
1513

16-
class BCHTestCase(unittest.TestCase):
14+
class Tests(unittest.TestCase):
1715
def exercise(self, *args, **kwargs):
18-
# create a bch object
1916
bch = bchlib.BCH(*args, **kwargs)
20-
max_data_len = (bch.n + 7) // 8 - (bch.ecc_bits + 7) // 8
17+
bits = bch.n - bch.ecc_bits
2118

22-
print('max_data_len: %d' % (max_data_len,))
23-
print('ecc_bits: %d (ecc_bytes: %d)' % (bch.ecc_bits, bch.ecc_bytes))
24-
print('m: %d' % (bch.m,))
25-
print('n: %d (%d bytes)' % (bch.n, bch.n // 8))
26-
print('prim_poly: 0x%x' % (bch.prim_poly,))
27-
print('t: %d' % (bch.t,))
19+
# print(f'data:\t{bits} bits (usable bytes: {bits // 8})')
20+
# print(f'ecc: \t{bch.ecc_bits} bits (bytes: {bch.ecc_bytes})')
21+
# print(f'm: \t{bch.m}')
22+
# print(f'n: \t{bch.n} ({(bch.n + 7) // 8} bytes)')
23+
# print(f'poly:\t{bch.prim_poly}')
24+
# print(f't: \t{bch.t}')
2825

29-
# random data
30-
data = bytearray(os.urandom(max_data_len))
31-
32-
# encode and make a "packet"
26+
data = bytearray(os.urandom(bits // 8))
3327
ecc = bch.encode(data)
34-
print('encoded ecc:', binascii.hexlify(ecc).decode('utf-8'))
3528
packet = data + ecc
29+
corrupted_packet = bytearray(packet)
3630

37-
# print hash of packet
38-
sha1_initial = hashlib.sha1(packet)
39-
print('packet sha1: %s' % (sha1_initial.hexdigest(),))
40-
41-
# make BCH_BITS errors
4231
for _ in range(bch.t):
43-
bitflip(packet, bch.n)
32+
bitflip(corrupted_packet)
4433

45-
# print hash of packet
46-
sha1_corrupt = hashlib.sha1(packet)
47-
print('packet sha1: %s' % (sha1_corrupt.hexdigest(),))
34+
corrupted_data = corrupted_packet[:-bch.ecc_bytes]
35+
corrupted_ecc = corrupted_packet[-bch.ecc_bytes:]
4836

49-
# de-packetize
50-
data, ecc = packet[:-bch.ecc_bytes], packet[-bch.ecc_bytes:]
37+
nerr = bch.decode(corrupted_data, corrupted_ecc)
38+
# print(f'nerr: \t{nerr}')
39+
assert(nerr >= 0)
40+
# print(bch.errloc)
5141

52-
# decode
53-
nerr = bch.decode(data, ecc)
42+
corrected_data = bytearray(corrupted_data)
43+
corrected_ecc = bytearray(corrupted_ecc)
44+
bch.correct(corrected_data, corrected_ecc)
45+
corrected_packet = corrected_data + corrected_ecc
5446

55-
print('nerr:', nerr)
56-
print('syn:', bch.syn)
57-
print('errloc:', bch.errloc)
47+
assert(corrected_packet == packet)
5848

59-
# correct
60-
bch.correct(data, ecc)
61-
62-
# packetize
63-
packet = data + ecc
49+
def test_t_eq_6_285(self):
50+
for _ in range(1000):
51+
self.exercise(6, prim_poly=285)
6452

65-
# print hash of packet
66-
sha1_corrected = hashlib.sha1(packet)
67-
print('packet sha1: %s' % (sha1_corrected.hexdigest(),))
53+
def test_t_eq_6_285_swap(self):
54+
for _ in range(1000):
55+
self.exercise(6, prim_poly=285, swap_bits=True)
6856

69-
if sha1_initial.digest() == sha1_corrected.digest():
70-
print('Corrected!')
71-
else:
72-
print('Failed')
57+
def test_t_eq_6_487(self):
58+
for _ in range(1000):
59+
self.exercise(6, prim_poly=487)
7360

74-
assert sha1_initial.digest() == sha1_corrected.digest()
61+
def test_t_eq_6_487_swap(self):
62+
for _ in range(1000):
63+
self.exercise(6, prim_poly=487, swap_bits=True)
7564

76-
def test_t_eq_6(self):
77-
self.exercise(6, prim_poly=487)
65+
def test_t_eq_12_17475(self):
66+
for _ in range(1000):
67+
self.exercise(12, prim_poly=17475)
7868

79-
def test_t_eq_12(self):
80-
self.exercise(12, prim_poly=17475, swap_bits=True)
69+
def test_t_eq_12_17475_swap(self):
70+
for _ in range(1000):
71+
self.exercise(12, prim_poly=17475, swap_bits=True)
8172

8273
def test_t_eq_16(self):
83-
self.exercise(16, m=13)
74+
for _ in range(1000):
75+
self.exercise(16, m=13)
76+
77+
def test_t_eq_16_swap(self):
78+
for _ in range(1000):
79+
self.exercise(16, m=13, swap_bits=True)
8480

8581
def test_t_eq_32(self):
86-
self.exercise(32, m=14)
82+
for _ in range(1000):
83+
self.exercise(32, m=14)
84+
85+
def test_t_eq_32_swap(self):
86+
for _ in range(1000):
87+
self.exercise(32, m=14, swap_bits=True)
8788

8889
def test_t_eq_64(self):
89-
self.exercise(64, m=15)
90+
for _ in range(1000):
91+
self.exercise(64, m=15)
92+
93+
def test_t_eq_64_swap(self):
94+
for _ in range(1000):
95+
self.exercise(64, m=15, swap_bits=True)
9096

9197
if __name__ == '__main__':
9298
unittest.main()

tests/test_exynos.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
"""16-bit ECC encoder as in the Samsung S5PV210 and Exynos NAND controllers"""
44

55
import bchlib
6-
import sys
76
import unittest
87

9-
class BCHTestCase(unittest.TestCase):
8+
class Tests(unittest.TestCase):
109
def test(self):
1110
ECC_POLY = 8219
1211
ECC_BITS = 16
@@ -26,10 +25,6 @@ def xor_ecc(ecc):
2625
ecc = bch.encode(b'\xFF' * 512)
2726
ecc = xor_ecc(ecc)
2827

29-
for c in ecc:
30-
print('%02X' % (c,), end=' ')
31-
print()
32-
3328
assert ecc == b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' \
3429
b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' \
3530
b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' \

tests/test_issue26.py

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)