view dcrypt/misc/checksums/Adler32.d @ 34:b1d9be1b3a34

Added additional overrides to Adler32 and CRC32 in dcrypt.misc.checksums in further hopes of D2 compatibility.
author Thomas Dixon <reikon@reikon.us>
date Thu, 14 May 2009 05:31:58 -0400
parents 21847420b1ac
children
line wrap: on
line source

/**
 * This file is part of the dcrypt project.
 *
 * Copyright: Copyright (C) dcrypt contributors 2008. All rights reserved.
 * License:   MIT
 * Authors:   Thomas Dixon
 */

module dcrypt.misc.checksums.Adler32;

import dcrypt.misc.Checksum;

/**
 * Implementation of Mark Adler's Adler32 checksum.
 * 
 * Conforms: RFC 1950
 * References: http://tools.ietf.org/html/rfc1950#page-10
 */
class Adler32 : Checksum
{
    private static const uint BASE = 65521;
    
    uint compute(void[] input_, uint start=1)
    {
        ubyte[] input = cast(ubyte[])input_;
        uint adler = start,
             s1 = adler & 0xffff,
             s2 = (adler >> 16) & 0xffff;
        
        foreach (ubyte i; input)
        {
            s1 = (s1 + i) % BASE;
            s2 = (s2 + s1) % BASE;
        }
        
        return (s2 << 16) + s1;
    }
    
    /** Play nice with D2's idea of const. */
    version (D_Version2)
    {
        uint compute(string input)
        {
            return compute(cast(ubyte[])input);
        }
    }
    
    string name()
    {
        return "Adler32";
    }
    
    debug (UnitTest)
    {
        unittest
        {
            static string[] test_inputs = [
                "",
                "a",
                "checksum",
                "chexksum"
            ];
            
            static const uint[] test_results = [
                0x1u,
                0x620062u,
                0xea10354u,
                0xf0a0369u
            ];
            
            Adler32 adler32 = new Adler32;
            foreach (uint i, string j; test_inputs)
                assert(adler32.compute(j) == test_results[i], adler32.name);
        }
    }
}