github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/crc/crc24.go (about)

     1  // Copyright 2021 DataStax
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package crc
    16  
    17  // Copied and adapted from the server-side version:
    18  // https://github.com/apache/cassandra/blob/cassandra-4.0/src/java/org/apache/cassandra/net/Crc.java
    19  
    20  const crc24Init uint32 = 0x875060
    21  const crc24Poly uint32 = 0x1974F0B
    22  
    23  // ChecksumKoopman returns the CRC-24 checksum of the given data.
    24  // The parameter bytes is an up to 8-byte register containing bytes to compute the CRC over; bits will be read
    25  // least-significant to most significant.
    26  // The parameter len is the number of bytes, greater than 0 and fewer than 9, to be read from bytes.
    27  // The polynomial is chosen from https://users.ece.cmu.edu/~koopman/crc/index.html, by Philip Koopman,
    28  // and is licensed under the Creative Commons Attribution 4.0 International License
    29  // (https://creativecommons.org/licenses/by/4.0).
    30  // Koopman's own notation to represent the polynomial has been changed.
    31  // This polynomial provides hamming distance of 8 for messages up to length 105 bits;
    32  // we only support 8-64 bits at present, with an expected range of 40-48.
    33  func ChecksumKoopman(data uint64, len int) uint32 {
    34  	crc := crc24Init
    35  	for i := 0; i < len; i++ {
    36  		crc ^= (uint32)(data) << 16
    37  		data >>= 8
    38  		for j := 0; j < 8; j++ {
    39  			crc <<= 1
    40  			if (crc & 0x1000000) != 0 {
    41  				crc ^= crc24Poly
    42  			}
    43  		}
    44  	}
    45  	return crc
    46  }