|
93 | 93 | import com.google.common.base.Charsets; |
94 | 94 | import com.google.common.math.DoubleMath; |
95 | 95 | import com.google.common.math.LongMath; |
| 96 | +import com.google.common.primitives.UnsignedBytes; |
96 | 97 | import com.google.common.util.concurrent.AsyncFunction; |
97 | 98 | import com.google.common.util.concurrent.Futures; |
98 | 99 | import com.google.common.util.concurrent.ListenableFuture; |
@@ -2716,6 +2717,49 @@ public static int crc32(byte[] bytes, int start, int end, int initialValue) { |
2716 | 2717 | return initialValue; |
2717 | 2718 | } |
2718 | 2719 |
|
| 2720 | + /** |
| 2721 | + * Returns the result of updating a CRC-16 with the specified bytes in a "most significant bit |
| 2722 | + * first" order. |
| 2723 | + * |
| 2724 | + * @param bytes Array containing the bytes to update the crc value with. |
| 2725 | + * @param start The start index (inclusive) of the byte range to update the crc with. |
| 2726 | + * @param end The end index (exclusive) of the byte range to update the crc with. |
| 2727 | + * @param initialValue The initial value for the crc calculation. The lower 16 bits of this 32-bit |
| 2728 | + * integer are used for the CRC computation. |
| 2729 | + * @return The result of updating the initial value with the specified bytes. |
| 2730 | + */ |
| 2731 | + public static int crc16(byte[] bytes, int start, int end, int initialValue) { |
| 2732 | + for (int i = start; i < end; i++) { |
| 2733 | + int value = UnsignedBytes.toInt(bytes[i]); |
| 2734 | + // Process one message byte to update the current CRC-16 value. |
| 2735 | + initialValue = crc16UpdateFourBits(value >> 4, initialValue); // High nibble first. |
| 2736 | + initialValue = crc16UpdateFourBits(value & 0x0F, initialValue); // Low nibble. |
| 2737 | + } |
| 2738 | + return initialValue; |
| 2739 | + } |
| 2740 | + |
| 2741 | + /** |
| 2742 | + * Process 4 bits of the message to update the CRC Value. Note that the data will be in the low |
| 2743 | + * nibble of value. |
| 2744 | + * |
| 2745 | + * @param value The 4-bit message data to be processed. |
| 2746 | + * @param crc16Register The current CRC-16 register to be updated. Only the lower 16 bits of this |
| 2747 | + * 32-bit integer are used for the CRC computation. |
| 2748 | + * @return The result of updating the CRC-16 register with the specified 4-bit message data. |
| 2749 | + */ |
| 2750 | + private static int crc16UpdateFourBits(int value, int crc16Register) { |
| 2751 | + // Step one, extract the most significant 4 bits of the CRC register. |
| 2752 | + int mostSignificant4Bits = (crc16Register >> 12) & 0xFF; |
| 2753 | + // XOR in the Message Data into the extracted bits. |
| 2754 | + mostSignificant4Bits = (mostSignificant4Bits ^ value) & 0xFF; |
| 2755 | + // Shift the CRC register left 4 bits. |
| 2756 | + crc16Register = (crc16Register << 4) & 0xFFFF; // Handle as 16 bit, discard any sign extension. |
| 2757 | + // Do the table look-ups and XOR the result into the CRC tables. |
| 2758 | + crc16Register = (crc16Register ^ CRC16_BYTES_MSBF[mostSignificant4Bits]) & 0xFFFF; |
| 2759 | + |
| 2760 | + return crc16Register; |
| 2761 | + } |
| 2762 | + |
2719 | 2763 | /** |
2720 | 2764 | * Returns the result of updating a CRC-8 with the specified bytes in a "most significant bit |
2721 | 2765 | * first" order. |
@@ -3671,6 +3715,16 @@ private static String maybeReplaceLegacyLanguageTags(String languageTag) { |
3671 | 3715 | 0XBCB4666D, 0XB8757BDA, 0XB5365D03, 0XB1F740B4 |
3672 | 3716 | }; |
3673 | 3717 |
|
| 3718 | + /** |
| 3719 | + * Allows the CRC-16 calculation to be done byte by byte instead of bit per bit in the order "most |
| 3720 | + * significant bit first". |
| 3721 | + */ |
| 3722 | + private static final int[] CRC16_BYTES_MSBF = |
| 3723 | + new int[] { |
| 3724 | + 0x0000, 0x01021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, |
| 3725 | + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF |
| 3726 | + }; |
| 3727 | + |
3674 | 3728 | /** |
3675 | 3729 | * Allows the CRC-8 calculation to be done byte by byte instead of bit per bit in the order "most |
3676 | 3730 | * significant bit first". |
|
0 commit comments