CRC

Bách khoa toàn thư mở Wikipedia
Bước tới: menu, tìm kiếm

CRC (cyclic redundancy check) là một loại hàm băm, được dùng để sinh ra giá trị kiểm thử, của một chuỗi bit có chiều dài ngắn và cố định, của các gói tin vận chuyển qua mạng hay một khối nhỏ của tệp dữ liệu. Giá trị kiểm thử được dùng để dò lỗi khi dữ liệu được truyền hay lưu vào thiết bị lưu trữ. Giá trị của CRC sẽ được tính toán và đính kèm vào dữ liệu trước khi dữ liệu được truyền đi hay lưu trữ. Khi dữ liệu được sử dụng, nó sẽ được kiểm thử bằng cách sinh ra mã CRC và so khớp với mã CRC trong dữ liệu.

CRC rất phổ biến, vì nó rất đơn giản để lắp đặt trong các máy tính sử dụng hệ cơ số nhị phân, dễ dàng phân tích tính đúng, và rất phù hợp để dò các lỗi gây ra bởi nhiễu trong khi truyền dữ liệu.

Giới thiệu[sửa | sửa mã nguồn]

CRC là một loại mã phát hiện lỗi. Cách tính toán của nó giống như phép toán chia số dài trong đó thương số được loại bỏ và số dư là kết quả, điểm khác biệt ở đây là sử dụng cách tính không nhớ (carry-less arithmetic) của một trường hữu hạn. Độ dài của số dư luôn nhỏ hơn hoặc bằng độ dài của số chia, do đó số chia sẻ quyết định độ dài có thể của kết quả trả về. Định nghĩa đối với từng loại CRC đặc thù quyết định số chia nào được sử dụng, cũng như nhiều ràng buộc khác.

Mặc dù các mã CRC có thể xây dựng được bằng cách sử dụng bất kỳ trường hữu hạn nào, nhưng tất cả các mã CRC thường dùng đều sử dụng trường hữu hạn GF(2). Đây là trường hai phần tử, thường được ký hiệu là 0 và 1, phù hợp với kiến trúc máy tính. Phần còn lại của bài viết sẽ chỉ đề cập đến những mã CRC thuộc dạng này, nhưng nguyên tắc thì khái quát hơn.

Một lý do quan trong lý giải sự phổ biến của mã CRC trong phát hiện sự thay đổi ngẫu nhiên của dữ liệu là hiệu suất đảm bảo. Điển hình, một mã CRC n bit, được áp dụng cho một đoạn dữ liệu có độ dài tùy ý, sẽ phát hiện được bất kỳ lỗi tín hiệu đơn nào có độ dài không quá n bit (nói cách khác, bất kỳ sự biến đổi đơn lẻ nào có chiều dài không quá n bit của dữ liệu), và sẽ phát hiện một phần 1-2-n của tất cả các lỗi tín hiệu có độ dài dài hơn thế. Các lỗi trong cả các kênh truyền dữ liệu và phương tiện bộ nhớ từ dẫn đến phân bố không ngẫu nhiên (v.d, "bursty"), làm cho các đặc tính của CRC trở nên hữu dụng hơn những mã khác như Multiple Parity checks.

Hệ thống tìm lỗi đơn giản nhất, bit parity (xét chẵn lẻ), thực ra là một mã CRC ở dạng tầm thường: sử dụng số chia độ dài 2 bit là 11.

Tính toán CRC[sửa | sửa mã nguồn]

Bài chi tiết: Tính toán CRC

Để tính toán một mã nhị phân n bit CRC, xếp các bít biểu diễn đầu vào thành một hàng, và đặt mẫu (n+1) bit biểu diễn số chia của CRC (gọi là một "đa thức") vào bên dưới bên trái ở cuối hàng. Sau đây là phép tính đầu tiên để tính một hàm CRC 3 bít:
Dãy số đầu vào:

11010011101100 
11010011101100 000 <--- Đầu vào (thêm vào bên phải dãy 3 bit 0)
1011               <--- Số chia (4 bit = 3 + 1 bit)
------------------
01100011101100 000 <--- Kết quả (--> Lại đưa vào đầu vào của phép tính tiếp theo)

Nếu dãy nhị phân đầu vào bên trên có bít cực tả (đầu tiên bên trái) là 0, không làm gì hết và dịch số chia sang phải một bít. Nếu dãy nhị phân đầu vào bên trên có bít cực tả là 1, lấy dãy số đầu vào trừ đi số chia (hay nói cách khác, lấy từng bít ở dãy số đầu vào trên trừ đi từng bít ở số chia). Số chia sau đó dịch vị trí 1 bít sang phải, quá trình cứ tiếp diễn như vậy đến khi số chia chạm tới tận cùng bên phải của dãy số đầu vào. Đây là phép tính cuối cùng:


00000000000101 000 <--- Kết quả của phép nhân
           101 1   <--- Số chia
------------------
00000000000000 100 <--- Số dư (3 bits)

Do cực tả của số chia sẻ làm các bít tương ứng của dãy số đầu vào trở về 0 qua mỗi lần dịch, khi quá trình này kết thúc, chỉ còn những bít ở dãy đầu vào có thể không là 0 trở thành n bit cuối bên phải của dãy số. n bit này là số dư của bước chia, và cũng sẽ là giá trị hàm CRC (trừ khi hàm CRC được chọn đặc biệt được gọi cho một số công đoạn tiền xử lý).

Những hàm CRC thường dùng và được tiêu chuẩn hóa[sửa | sửa mã nguồn]

Các dạng mã kiểm soát lỗi CRC (cyclic redundancy check) được chia thành nhiều tiêu chuẩn, chúng không được tiêu chuẩn hóa thống nhất cho 1 thuật toán nào ở mỗi mức độ trên toàn cầu: có 3 đa thức CRC-12[1], ít nhất 8 biến thể có trong tài liệu của CRC-16, và 3 biến thể của CRC-32[2] được biết đến. Các đa thức thường được xem như không phải là tối ưu nhất có thể. Trong những năm từ 1993 đến 2004, Koopman, Castagnoli và một số nhà khoa học đã tiến hành tìm kiếm trong không gian các đa thức lên đến 16[3], và không gian 24 và 32 bit,[4][5] tìm các ví dụ có hiệu suất tốt hơn nữa (trong các điều kiện quãng cách Hamming cho một bức tin có kích thước cho trước) so với các đã thức trong các giao thức trước đó, và xuất bản những kết quả tốt nhất trong số chúng với mục đích cải thiện năng lực tìm lỗi cho cac tiêu chuẩn trong tương lai[5].

Không phải ngẫu nhiên mà đa thức phổ biển CRC-32, được IEEE giới thiệu và được dùng trong V.42, Ethernet, FDDIZIP và các file PNG cũng như nhiều ứng dụng khác, là một đa thức sinh ra từ mã Hamming và được chọn để tìm lỗi[6] trong các kênh truyền thông. Dù vậy, nó còn có hiệu suất tốt hơn với đa thức Castagnoli CRC-32C sử dụng ở iSCSI[5] trong các môi trường Internet SCSI.

Bảng dưới đây chỉ liệt kê những đa thức của những thuật toán đa dạng đang được sử dụng.

Tên Đa thức Các biểu diễn: thông thường hoặc nghịch đảo (đảo của đảo)
CRC-1 x + 1 (hầu hết phần cứng; còn biết với tên parity bit) 0x1 hoặc 0x1 (0x1)
CRC-4-ITU x^4 + x + 1 (ITU G.704, p. 12) 0x3 hoặc 0xC (0x9)
CRC-5-ITU x^5 + x^4 + x^2 + 1 (ITU G.704, p. 9) 0x15 hoặc 0x15 (0x1A)
CRC-5-USB x^5 + x^2 + 1 (USB token packets) 0x05 hoặc 0x14 (0x12)
CRC-6-ITU x^6 + x + 1 (ITU G.704, p. 3) 0x03 hoặc 0x30 (0x21)
CRC-7 x^7 + x^3 + 1 (Các hệ thống viễn thông, MMC,SD) 0x09 hoặc 0x48 (0x44)
CRC-8-ATM x^8 + x^2 + x + 1 (ATM HEC) 0x07 hoặc 0xE0 (0x83)
CRC-8-CCITT x^8 + x^7 + x^3 + x^2 + 1 (1-Wire bus) 0x8D hoặc 0xB1 (0xC6)
CRC-8-Dallas/Maxim x^8 + x^5 + x^4 + 1 (1-Wire bus) 0x31 hoặc 0x8C (0x98)
CRC-8 x^8 + x^7 + x^6 + x^4 + x^2 + 1 0xD5 hoặc 0xAB (0xEA [3])
CRC-8-SAE J1850 x^8 + x^4 + x^3 + x^2 + 1 0x1D hoặc 0xB8 (0x8E)
CRC-10 x^{10} + x^9 + x^5 + x^4 + x + 1 0x233 hoặc 0x331 (0x319)
CRC-11 x^{11} + x^9 + x^8 + x^7 + x^2 + 1 (FlexRay) 0x385 hoặc 0x50E (0x5C2)
CRC-12 x^{12} + x^{11} + x^3 + x^2 + x + 1 (Các hệ thống viễn thông,[7][8]) 0x80F or 0xF01 (0xC07)
CRC-15-CAN x^{15} + x^{14} + x^{10} + x^8 + x^7 + x^4 + x^3 + 1 0x4599 hoặc 0x4CD1 (0x62CC)
CRC-16-Fletcher Không phải một CRC; xem Fletcher's checksum Sử dụng trong Adler-32 A & B CRC
CRC-16-CCITT x^{16} + x^{12} + x^5 + 1 (X.25, V.41, CDMA, Bluetooth, XMODEM, HDLC,PPP, IrDA, BACnet; được gọi là CRC-CCITT, MMC,SD) 0x1021 hoặc 0x8408 (0x8810 [3])
CRC-16-DNP x^{16} + x^{13} + x^{12} + x^{11} + x^{10} + x^8 + x^6 + x^5 + x^2 + 1 (DNP, IEC 870, M-Bus) 0x3D65 hoặc 0xA6BC (0x9EB2)
CRC-16-IBM x^{16} + x^{15} + x^2 + 1 (SDLC, USB, khác; còn được biết là CRC-16) 0x8005 hoặc 0xA001 (0xC002)
CRC-24-Radix-64  x^{24} + x^{23} + x^{18} + x^{17} + x^{14} + x^{11} + x^{10} + x^7 + x^6 + x^5 + x^4 + x^3 + x + 1 (FlexRay) 0x864CFB hoặc 0xDF3261 (0xC3267D)
CRC-30 x^{30} + x^{29} + x^{21} + x^{20} + x^{15} + x^{13} + x^{12} + x^{11} + x^{8} + x^{7} + x^{6} + x^{2} + x + 1 (CDMA) 0x2030B9C7 hoặc 0x38E74301 (0x30185CE3)
CRC-32-Adler Không phải một CRC; xem Adler-32 xem Adler-32
CRC-32-IEEE 802.3 x^{32} + x^{26} + x^{23} + x^{22} + x^{16} + x^{12} + x^{11} + x^{10} + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 (V.42, MPEG-2, PNG [9]) 0x04C11DB7 hoặc 0xEDB88320 (0x82608EDB [5])
CRC-32C (Castagnoli) x^{32} + x^{28} + x^{27} + x^{26} + x^{25} + x^{23} + x^{22} + x^{20} + x^{19} + x^{18} + x^{14} + x^{13} + x^{11} + x^{10} + x^9 + x^8 + x^6 + 1 0x1EDC6F41 hoặc 0x82F63B78 (0x8F6E37A0 [5])
CRC-32K (Koopman) x^{32} + x^{30} + x^{29} + x^{28} + x^{26} + x^{20} + x^{19} + x^{17} + x^{16} + x^{15} + x^{11} + x^{10} + x^{7} + x^{6} + x^{4} + x^{2} + x + 1 0x741B8CD7 hoặc 0xEB31D82E (0xBA0DC66B [5])
CRC-64-ISO x^{64} + x^4 + x^3 + x + 1 (HDLC — ISO 3309) 0x000000000000001B hoặc 0xD800000000000000 (0x800000000000000D)
CRC-64-ECMA-182 x^{64} + x^{62} + x^{57} + x^{55} + x^{54} + x^{53} + x^{52} + x^{47} + x^{46} + x^{45} + x^{40} + x^{39} + x^{38} + x^{37} + x^{35} + x^{33} + x^{32} + x^{31} + x^{29} + x^{27} + x^{24} + x^{23} + x^{22} + x^{21} + x^{19} + x^{17} + x^{13} + x^{12} + x^{10} + x^9 + x^7 + x^4 + x + 1 (as described in ECMA-182 p. 63) 0x42F0E1EBA9EA3693 hoặc 0xC96C5795D7870F42 (0xA17870F5D4F51B49)

Đã từng tồn tại, nhưng không còn sử dụng trong công nghệ—hầu hết được thay thế bằng các hàm mật mã băm (cryptographic hash functions):

  • CRC-128 (IEEE)
  • CRC-256 (IEEE)

Xung đột mã CRC[sửa | sửa mã nguồn]

Xem thêm[sửa | sửa mã nguồn]

Tham khảo[sửa | sửa mã nguồn]

  1. ^ “(slib) Cyclic Checksum”. Truy cập ngày 6 tháng 4 năm 2008. 
  2. ^ Greg Cook (9 tháng 9 năm 2008). “Catalogue of parameterised CRC algorithms”. Truy cập ngày 9 tháng 9 năm 2008. 
  3. ^ a ă â [Philip]; Chakravarty, Tridib (2004), Cyclic Redundancy Code (CRC) Polynomial Selection For Embedded Networks 
  4. ^ Castagnoli, G.; S. Braeuer; M. Herrman (tháng 6 năm 1993). “Optimization of Cyclic Redundancy-Check Codes with 24 and 32 Parity Bits”. IEEE Transactions on Communications 41 (6): 883. doi:10.1109/26.231911. ISSN 0090-6778. . Castagnoli's et al. work on algorithmic selection of CRC polynomials
  5. ^ a ă â b c d Koopman, P. (tháng 6 năm 2002). “32-Bit Cyclic Redundancy Codes for Internet Applications”. The International Conference on Dependable Systems and Networks: 459. doi:10.1109/DSN.2002.1028931. . Verification of Castagnoli's results by exhaustive search and some new good polynomials
  6. ^ Lỗi chú thích: Thẻ <ref> sai; không có nội dung trong thẻ ref có tên BrayerHammond1975
  7. ^ Perez, A.; Wismer & Becker (1983). “Byte-Wise CRC Calculations”. IEEE Micro 3 (3): 40–50. doi:10.1109/MM.1983.291120. ISSN 0272-1732. 
  8. ^ Ramabadran, T.V.; Gaitonde, S.S. (1988). “A tutorial on CRC computations”. IEEE Micro 8 (4): 62–75. doi:10.1109/40.7773. ISSN 0272-1732. 
  9. ^ Thomas Boutell, Glenn Randers-Pehrson, et al. (14 tháng 7 năm 1998). “PNG (Portable Network Graphics) Specification, Version 1.2”. Truy cập ngày 28 tháng 4 năm 2008. 

Liên kết ngoài[sửa | sửa mã nguồn]