1 /** 2 * Adler32 3 * 4 * Copyright: 5 * (C) 1999-2007 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.checksum.adler32; 12 13 import botan.constants; 14 static if (BOTAN_HAS_ADLER32): 15 16 import botan.utils.loadstor; 17 import botan.hash.hash; 18 /** 19 * The Adler32 checksum, used in zlib 20 */ 21 final class Adler32 : HashFunction 22 { 23 public: 24 override @property string name() const { return "Adler32"; } 25 override @property size_t outputLength() const { return 4; } 26 override @property size_t hashBlockSize() const { return 0; } 27 override HashFunction clone() const { return new Adler32; } 28 29 override void clear() { m_S1 = 1; m_S2 = 0; } 30 31 this() { clear(); } 32 ~this() { clear(); } 33 protected: 34 /* 35 * Update an Adler32 Checksum 36 */ 37 override void addData(const(ubyte)* input, size_t length) 38 { 39 __gshared immutable size_t PROCESS_AMOUNT = 5552; 40 41 while (length >= PROCESS_AMOUNT) 42 { 43 adler32Update(input, PROCESS_AMOUNT, m_S1, m_S2); 44 input += PROCESS_AMOUNT; 45 length -= PROCESS_AMOUNT; 46 } 47 48 adler32Update(input, length, m_S1, m_S2); 49 } 50 51 /* 52 * Finalize an Adler32 Checksum 53 */ 54 override void finalResult(ubyte* output) 55 { 56 storeBigEndian(output, m_S2, m_S1); 57 clear(); 58 } 59 60 ushort m_S1, m_S2; 61 } 62 63 package: 64 65 void adler32Update(const(ubyte)* input, size_t length, ref ushort S1, ref ushort S2) 66 { 67 uint S1x = S1; 68 uint S2x = S2; 69 70 while (length >= 16) 71 { 72 S1x += input[ 0]; S2x += S1x; 73 S1x += input[ 1]; S2x += S1x; 74 S1x += input[ 2]; S2x += S1x; 75 S1x += input[ 3]; S2x += S1x; 76 S1x += input[ 4]; S2x += S1x; 77 S1x += input[ 5]; S2x += S1x; 78 S1x += input[ 6]; S2x += S1x; 79 S1x += input[ 7]; S2x += S1x; 80 S1x += input[ 8]; S2x += S1x; 81 S1x += input[ 9]; S2x += S1x; 82 S1x += input[10]; S2x += S1x; 83 S1x += input[11]; S2x += S1x; 84 S1x += input[12]; S2x += S1x; 85 S1x += input[13]; S2x += S1x; 86 S1x += input[14]; S2x += S1x; 87 S1x += input[15]; S2x += S1x; 88 input += 16; 89 length -= 16; 90 } 91 92 foreach (size_t j; 0 .. length) 93 { 94 S1x += input[j]; 95 S2x += S1x; 96 } 97 98 S1 = S1x % 65521; 99 S2 = S2x % 65521; 100 } 101