crc32.txt: standardize document format

Each text file under Documentation follows a different
format. Some doesn't even have titles!

Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:

- Add a title for the document;
- Mark literal blocks.

While here, replace a comma by a dot at the end of a paragraph.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
This commit is contained in:
Mauro Carvalho Chehab 2017-05-14 09:56:02 -03:00 committed by Jonathan Corbet
parent e8cb6f1edc
commit 2e4e6f30f7

View File

@ -1,4 +1,6 @@
A brief CRC tutorial. =================================
brief tutorial on CRC computation
=================================
A CRC is a long-division remainder. You add the CRC to the message, A CRC is a long-division remainder. You add the CRC to the message,
and the whole thing (message+CRC) is a multiple of the given and the whole thing (message+CRC) is a multiple of the given
@ -8,7 +10,8 @@ remainder computed on the message+CRC is 0. This latter approach
is used by a lot of hardware implementations, and is why so many is used by a lot of hardware implementations, and is why so many
protocols put the end-of-frame flag after the CRC. protocols put the end-of-frame flag after the CRC.
It's actually the same long division you learned in school, except that It's actually the same long division you learned in school, except that:
- We're working in binary, so the digits are only 0 and 1, and - We're working in binary, so the digits are only 0 and 1, and
- When dividing polynomials, there are no carries. Rather than add and - When dividing polynomials, there are no carries. Rather than add and
subtract, we just xor. Thus, we tend to get a bit sloppy about subtract, we just xor. Thus, we tend to get a bit sloppy about
@ -40,7 +43,8 @@ throw the quotient bit away, but subtract the appropriate multiple of
the polynomial from the remainder and we're back to where we started, the polynomial from the remainder and we're back to where we started,
ready to process the next bit. ready to process the next bit.
A big-endian CRC written this way would be coded like: A big-endian CRC written this way would be coded like::
for (i = 0; i < input_bits; i++) { for (i = 0; i < input_bits; i++) {
multiple = remainder & 0x80000000 ? CRCPOLY : 0; multiple = remainder & 0x80000000 ? CRCPOLY : 0;
remainder = (remainder << 1 | next_input_bit()) ^ multiple; remainder = (remainder << 1 | next_input_bit()) ^ multiple;
@ -54,12 +58,12 @@ the remainder don't actually affect any decision-making until
32 bits later. Thus, the first 32 cycles of this are pretty boring. 32 bits later. Thus, the first 32 cycles of this are pretty boring.
Also, to add the CRC to a message, we need a 32-bit-long hole for it at Also, to add the CRC to a message, we need a 32-bit-long hole for it at
the end, so we have to add 32 extra cycles shifting in zeros at the the end, so we have to add 32 extra cycles shifting in zeros at the
end of every message, end of every message.
These details lead to a standard trick: rearrange merging in the These details lead to a standard trick: rearrange merging in the
next_input_bit() until the moment it's needed. Then the first 32 cycles next_input_bit() until the moment it's needed. Then the first 32 cycles
can be precomputed, and merging in the final 32 zero bits to make room can be precomputed, and merging in the final 32 zero bits to make room
for the CRC can be skipped entirely. This changes the code to: for the CRC can be skipped entirely. This changes the code to::
for (i = 0; i < input_bits; i++) { for (i = 0; i < input_bits; i++) {
remainder ^= next_input_bit() << 31; remainder ^= next_input_bit() << 31;
@ -67,7 +71,8 @@ for (i = 0; i < input_bits; i++) {
remainder = (remainder << 1) ^ multiple; remainder = (remainder << 1) ^ multiple;
} }
With this optimization, the little-endian code is particularly simple: With this optimization, the little-endian code is particularly simple::
for (i = 0; i < input_bits; i++) { for (i = 0; i < input_bits; i++) {
remainder ^= next_input_bit(); remainder ^= next_input_bit();
multiple = (remainder & 1) ? CRCPOLY : 0; multiple = (remainder & 1) ? CRCPOLY : 0;
@ -81,7 +86,8 @@ be bit-reversed) and next_input_bit().
As long as next_input_bit is returning the bits in a sensible order, we don't As long as next_input_bit is returning the bits in a sensible order, we don't
*have* to wait until the last possible moment to merge in additional bits. *have* to wait until the last possible moment to merge in additional bits.
We can do it 8 bits at a time rather than 1 bit at a time: We can do it 8 bits at a time rather than 1 bit at a time::
for (i = 0; i < input_bytes; i++) { for (i = 0; i < input_bytes; i++) {
remainder ^= next_input_byte() << 24; remainder ^= next_input_byte() << 24;
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
@ -90,7 +96,8 @@ for (i = 0; i < input_bytes; i++) {
} }
} }
Or in little-endian: Or in little-endian::
for (i = 0; i < input_bytes; i++) { for (i = 0; i < input_bytes; i++) {
remainder ^= next_input_byte(); remainder ^= next_input_byte();
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {