13ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin/*
23ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * Copyright (C) 2011 The Guava Authors
33ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin *
43ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
53ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * in compliance with the License. You may obtain a copy of the License at
63ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin *
73ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0
83ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin *
93ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * Unless required by applicable law or agreed to in writing, software distributed under the License
103ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
113ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * or implied. See the License for the specific language governing permissions and limitations under
123ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * the License.
133ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin */
143ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
153ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinpackage com.google.common.hash;
163ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
173ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin/**
183ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * This class generates a CRC32C checksum, defined by RFC 3720, Section 12.1.
193ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * The generator polynomial for this checksum is {@code 0x11EDC6F41}.
203ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin *
213ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin * @author Kurt Alfred Kluever
223ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin */
233ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinfinal class Crc32cHashFunction extends AbstractStreamingHashFunction {
243ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
253ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @Override
263ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public int bits() {
273ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    return 32;
283ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
293ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
303ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @Override
313ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public Hasher newHasher() {
323ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    return new Crc32cHasher();
333ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
343ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
353ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @Override
363ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public String toString() {
373ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    return "Hashing.crc32c()";
383ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
393ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
403ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  static final class Crc32cHasher extends AbstractByteHasher {
413ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
423ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    // The CRC table, generated from the polynomial 0x11EDC6F41.
433ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    static final int[] CRC_TABLE = {
443ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4,
453ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
463ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
473ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24,
483ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b,
493ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
503ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54,
513ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b,
523ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a,
533ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35,
543ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5,
553ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
563ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45,
573ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a,
583ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a,
593ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595,
603ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48,
613ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
623ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687,
633ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198,
643ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927,
653ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38,
663ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8,
673ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
683ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096,
693ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789,
703ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859,
713ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46,
723ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9,
733ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
743ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36,
753ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829,
763ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c,
773ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93,
783ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043,
793ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
803ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3,
813ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc,
823ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c,
833ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033,
843ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652,
853ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
863ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d,
873ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982,
883ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d,
893ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622,
903ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2,
913ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
923ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530,
933ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f,
943ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff,
953ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0,
963ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f,
973ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
983ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90,
993ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f,
1003ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee,
1013ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1,
1023ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321,
1033ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
1043ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81,
1053ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e,
1063ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,
1073ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351
1083ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    };
1093ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
1103ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    private int crc = 0;
1113ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
1123ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    @Override
1133ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    public void update(byte b) {
1143ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      crc ^= 0xFFFFFFFF;
1153ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      // See Hacker's Delight 2nd Edition, Figure 14-7.
1163ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      crc = ~((crc >>> 8) ^ CRC_TABLE[(crc ^ b) & 0xFF]);
1173ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
1183ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
1193ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    @Override
1203ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    public HashCode hash() {
1213ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      return HashCode.fromInt(crc);
1223ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
1233ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
1243ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin}
125