Mã Hamming (7,4) trở lại năm 1950. Trước đó Richard Hamming làm việc như một nhà toán học tại Bell Labs. Mỗi Thứ Sáu Hamming thiết lập các máy tính để thực hiện một loạt tính toán và thu thập kết quả vào thứ Hai sau. Sử dụng kiểm tra chẵn lẻ, các máy này có thể phát hiện lỗi trong quá trình tính toán. Thất vọng, vì nhận được thông báo lỗi quá thường xuyên, Hamming quyết định cải thiện phát hiện lỗi và phát hiện ra các mã Hamming nổi tiếng.
Cơ học của Hamming (7,4)
Mục tiêu của mã Hamming là tạo ra một tập hợp các bit chẵn lẻ trùng nhau sao cho một lỗi một bit (một bit bị lật) trong một bit dữ liệu hoặc một bit chẵn lẻ có thể được phát hiện và sửa chữa. Chỉ khi xảy ra nhiều lỗi, mã Hamming không thể khôi phục dữ liệu gốc. Nó có thể không nhận thấy một lỗi nào cả, hoặc thậm chí sửa nó sai. Do đó, trong thử thách này, chúng tôi sẽ chỉ xử lý các lỗi đơn bit.
Để làm ví dụ về mã Hamming, chúng ta sẽ xem xét mã Hamming (7,4). Ngoài ra với 4 bit dữ liệu, d1, d2, d3, d4
nó sử dụng 3 bit chẵn lẻ p1, p2, p3
, được tính bằng các phương trình sau:
p1 = (d1 + d2 + d4) % 2
p2 = (d1 + d3 + d4) % 2
p3 = (d2 + d3 + d4) % 2
Từ mã kết quả (dữ liệu + bit chẵn lẻ) có dạng p1 p2 d1 p3 d2 d3 d4
.
Phát hiện lỗi hoạt động theo cách sau. Bạn tính toán lại các bit chẵn lẻ và kiểm tra xem chúng có khớp với các bit chẵn lẻ nhận được không. Trong bảng sau đây bạn có thể thấy, mỗi loại lỗi một bit đều mang lại sự khớp khác nhau của các bit chẵn lẻ. Do đó, mọi lỗi đơn bit có thể được bản địa hóa và sửa chữa.
error in bit | p1 | p2 | d1 | p3 | d2 | d3 | d4 | no error
-------------|---------------------------------------------
p1 matches | no | yes| no | yes| no | yes| no | yes
p2 matches | yes| no | no | yes| yes| no | no | yes
p3 matches | yes| yes| yes| no | no | no | no | yes
Thí dụ
Hãy để dữ liệu của bạn được 1011
. Các bit chẵn lẻ là p1 = 1 + 0 + 1 = 0
, p2 = 1 + 1 + 1 = 1
và p3 = 0 + 1 + 1 = 0
. Kết hợp dữ liệu và các bit chẵn lẻ và bạn có được từ mã 0110011
.
data bits | 1 011
parity bits | 01 0
--------------------
codeword | 0110011
Hãy nói trong khi truyền hoặc tính toán bit thứ 6 (= bit dữ liệu thứ 3) lật. Bạn nhận được từ 0110001
. Các dữ liệu bị cáo buộc nhận được là 1001
. Bạn tính toán các bit chẵn lẻ nữa p1 = 1 + 0 + 1 = 0
, p2 = 1 + 0 + 1 = 0
, p3 = 0 + 0 + 1 = 1
. Chỉ p1
khớp với các bit chẵn lẻ của từ mã 0110001
. Do đó, một lỗi xảy ra. Nhìn vào bảng trên, cho chúng tôi biết rằng lỗi xảy ra d3
và bạn có thể khôi phục dữ liệu gốc 1011
.
Thử thách:
Viết một hàm hoặc một chương trình, nhận một từ (7 bit), một trong các bit có thể sai và khôi phục dữ liệu gốc. Định dạng đầu vào (thông qua STDIN, đối số dòng lệnh, đối số dấu nhắc hoặc hàm) có thể là một chuỗi "0110001"
, một danh sách hoặc một mảng [0, 1, 1, 0, 0, 0, 1]
hoặc một số nguyên trong MSB 0b0110001 = 49
. Như mô tả ở trên, thứ tự của đầu vào là p1 p2 d1 p3 d2 d3 d4
. Đầu ra (thông qua giá trị trả về hoặc STDOUT) phải có cùng định dạng, nhưng theo thứ tự d1 d2 d3 d4
. Chỉ trả về / xuất 4 bit dữ liệu.
Đây là mã golf. Do đó mã ngắn nhất sẽ thắng.
Các trường hợp thử nghiệm:
1110000 -> 1000 # no error
1100000 -> 1000 # error at 1st data bit
1111011 -> 1111 # error at 2nd data bit
0110001 -> 1011 # error at 3rd data bit (example)
1011011 -> 1010 # error at 4th data bit
0101001 -> 0001 # error at 1st parity bit
1010000 -> 1000 # error at 2nd parity bit
0100010 -> 0010 # error at 3rd parity bit
[is_p3_wrong][is_p2_wrong][is_p1_wrong]
ở cơ sở hai, nó sẽ đưa ra vị trí của bit không chính xác trong từ. (Dựa trên bảng trong câu hỏi.) Điều này có thể sẽ hữu ích cho một số thuật toán.