I have a question regarding the non-linearity of the CRC32 in gnuradio.
I am working on a project where i need a linear CRC32 meaning that: crc(a xor b) = crc(a) xor crc(b), where a and b represent a packet.
The implementation of CRC32 in gnuradio is by default non-linear so i had to modify the code to make it linear.
I did some research on the theory behind CRC and i found out 2 reasons behind a non-linear CRC implementation:
1- with a linear CRC, we can have the same CRC for 2 different packets of zeros, for example crc(0000 0000) = crc(00000 00 00000). So if i add additional zeroes to a packet containing only zeros, well, the CRC will nont be able to detect the errors(additional zeros).
2- the second reason is that with a linear CRC, if i add zeros to the beginning of a packet, the CRC won't be able to detect the errors. for example: crc(10010 1101) = crc(0000 1000 1101)
Now my question is:
When transmitting packets between two USRPs, bits could have errors(due to bad SNR for example), so a bit "1" could become a bit "0" and vice versa. However, I don't think that bits could be added (like the two cases stated above) to the packets and thus the reasons of implementing a non-linear CRC should not apply to gnuradio.
So why do we have a non-linear CRC in gnuradio by default?
And, if i use a linear CRC when trasmitting between two USRP, would that be a problem?
Thank you,
Such CRCs are still linear, just with an added constant. As an analogy, y = a x is linear, but so is y = a x + b, where b is a non-zero constant.
In this case, crc(a xor b) xor crc(a) xor crc(b) is a constant for all equal length messages a and b. That constant is crc(0), i.e. the CRC of all zeros of that same message length.
There is absolutely no problem whatsoever with this sort of linearity, and in fact it has benefits. In particular, a change in the message that adds a prefix of zeros would be detected as an error.
Related
How exactly do the V and S flags function on the ATMEGA328?
The ATMEGA328 has separate sign (S), carry (C), 2's complement overflow (V) and negative (N) flags. N is the MSB (corresponding to the sign bit on other processors). How exactly the V flag operates is not well explained in the datasheet. As I understand it, V is generally calculated as N⊕C. But S is defined in the datasheet as V⊕N which implies that it equals N⊕N⊕C or just C. If that's true then it doesn't make much sense to have a separate flag for it so I suspect I've misunderstood something here.
V is not generally the same as N XOR C.
I found a counterexample by looking at the ADC (Add with Carry) instruction in the manual and considering what would happen if you add 0xFF to 0x02 to get 0x01.
C would be 1 because 0xFF + 0x02 = 0x101, which is larger than 0xFF, so there is a carry from the most significant bit of the addition.
N would be 0 because it is simply the MSB of the result.
V would be 0 because it is defined to be 1 if two's complement overflow happened. From the perspective of two's complement, we simply added -1 and 2 to get 1, so there is no overflow. And you can confirm this by carefully evaluating the formula in the manual to calculate V.
With reference to this article:
https://www.digikey.com/eewiki/display/microcontroller/CRC+Basics
The polynomial key is an important part of the CRC. Keys are not just random polynomials; they are generated using a set of mathematical formulas and are intended to increase the number of mistakes that the CRC process identifies. The polynomial is typically defined by the network protocol or external device. Since there is a well-established set of keys available, the processes for defining keys is not discussed here.
I understand how the calculation of CRC with a given polynomial key, however, how does one generate the polynomial key, and to ensure it can catch as much error as possible with a given set of protocal?
I assume the polynomial key has something to do with:
data lengh
data speed
others?
The part about using mathematical formulas to generate CRC polynomials is somewhat misleading. The number of 1 bits in a CRC polynomial is the maximum possible Hamming distance (HD)for the polynomial, and generally the actual Hamming distance will be less depending on the data length. The maximum bit error detection is the Hamming distance - 1.
Generally CRC polynomials that detect a higher number of bits are the product of multiple prime polynomials. For example, for a 32 bit CRC that can detect up to 7 errors for data + crc length = 1024 bits, the 33 bit CRC polynomial 0x1f1922815 = 0x787*0x557*0x465*0x3*0x3. The 0x3 factor will detect any odd number of bit errors, so the CRC needs to detect all possible 6 bit errors in 1024 bits.
I'm not aware of a formula to determine the maximum bit error detection, and generally a somewhat optimized brute force search is done. As an example, say a 32 bit CRC polynomial is being checked to see if it can detect all 6 bit errors for data + crc length of 1024 bits, the number of possible 6 bit error patterns in 1024 bits is comb(1024,6) = 1,577,953,087,760,896. To reduce this to something reasonable, the number of possible 3 bit errors, comb(1024,3) = 178,433,024, is used to create a large table, each entry containing the CRC and 3 bit indexes. The table is sorted, and then used to check for collisions where a 3 bit pattern's CRC is the same as a different 3 bit pattern's CRC. A check for failure for 4 bit patterns will also be needed (checking for collisions between two different 2 bit patterns).
Generally as the data length gets smaller, the maximum number of error bits guaranteed to be detected increases. Here is a link to a bunch of CRC polynomials and their error detection capability.
https://users.ece.cmu.edu/~koopman/crc/crc32.html
The notes page explains the table entries:
http://users.ece.cmu.edu/~koopman/crc/notes.html
I'm implementing a QR code generation algorithm as explained on thonky.com and I'm trying to understand one of the cases:
as stated in this page and this page I can deduct that if the code is protected with M error correction level, and the chosen mask is No. 0, the first 5 bits of the format string (non-XORed) are '00000', and because of this the whole string of 15 bits is zeros.
the next step is to remove all leading zeros, which are, again, all of them. it means that there's nothing to XOR the generator polynomial string(10100110111) with, thus giving us a final string of 15 zeros, which means that the final (XORed) string will be simply the mask string (101010000010010).
I'm seeking for confirmation that my logic is right.
Thank you all very much in advance for the help.
Your logic is correct.
remove all leading zeroes
The actual process could be described as appending 10 zero bits to the 5 bits of data and treating the 15 bits as 15 single bit coefficients of a polynomial, then dividing that polynomial by the 11 bit generator polynomial resulting in a 10 bit remainder polynomial, which is then subtracted from the 5 data bits + 10 zero bits polynomial. Since this is binary math, add and subtract are both xor operations, and since the 10 appended bits are zero bits, the process can just append the 10 remainder bits to the 5 data bits.
As commented above, rather than actually implementing a BCH encode function, since there are only 32 possible format strings, you can just do a table lookup.
https://www.thonky.com/qr-code-tutorial/format-version-tables
I'm currently building a 16 bit ALU using Logisim (ie logic gates only), and am stuck on a division process. I am currently just using the simple standard "division algorithm loop" (as shown below):
Read input values;
Compare input values. Wait until comparison process has finished;
If A<B go to step 10. If A≥B, go to next step;
Subtract B from A;
Wait until subtraction process has finished;
Add one to count;
Wait until counting process has finished;
Write value from subtraction process to input;
Go to step 1;
Answer is count remainder A
This, however, takes a very long time for processes with large answers (repeating a 300 tick cycle 65,000 times isn't fun).
I'm just wondering if there are similar algorithms which are quicker (that exclusively use addition and/or subtraction and/or multiplication and any boolean logic) that could be implemented using logic gates.
Any help or ideas would be greatly appreciated!
Fraser
Use long-division. In binary, there is no multiplication, since the quotient at each bit position can only be 1 or 0. So it can be implemented as a conditional subtract (subtract if result non-negative) and shift.
That's just a crude outline, of course.
A typical approach for a 32/16:16+16 division would be to have the dividend stored in a pair of 16-bit registers (which get updated during operation) and the divisor in its own register (which doesn't). Sixteen times, subtract the upper 17 bits of the dividend from the divisor; if a borrow results, discard the result and shift the divisor left one place, putting a 0 into the lsb. If no borrow results, store the result into the divisor while shifting it left, but put a 1 into the lsb. After sixteen such steps, the lower 16 bits of the dividend register will hold the quotient, and the upper 16 bits will hold the remainder. Note that this operation will only work if the quotient is representable in 16 bits. Note also that on a processor which implements 32/16:16+16 division in this fashion, one may conveniently divide arbitrarily-large numbers by a 16-bit quantity, since the upper 16 bits of dividend for each step should be the remainder from the previous step.
My current textbook (Information Security: Principles and Practice by Mark Stamp) discusses how to determine the CRC of data via long-division, using XOR instead of subtraction to determine the remainder.
If our divisor has N-bits, we append (N-1) 0 bits to the dividend (the data) and then use long-division with XOR to solve for the CRC.
For example:
Divisor: 10011
Dividend: 10101011
101010110000 / 10011 = 10110110 R 1010, where 1010 = CRC
I'm able to perform this computation fine. However, the book mentions that in the case of the divisor being 10011, it's easy to find collisions.
I'm missing something here -- why is it easier to find a collision when the divisor is 10011?
See http://en.wikipedia.org/wiki/Cyclic_redundancy_check#Designing_CRC_polynomials for more details.
10011 corresponds to polynomial x^5+x+1 which is irreducible. And, using such codes decreases the chance of collisions.