-- The Adler32 checksum from zlib

create or replace function
adler32(
	buf in varchar2,
	adler in number := 1
) return number
deterministic
is
	s1 number;
	s2 number;
	signed boolean;
	currchar number;
	our_adler number;
begin
        -- Modulo 2**32 to protect ourselves
	our_adler := mod(adler,4294967296);
        if buf is null then
        	return our_adler;
        end if;
        -- Oracle's bitwise and works on integers (which are signed and in
        -- the range -2**31..2**31)
        -- Any number above 2**31 would generate a numeric overflow
        -- Solution: substract 2**31 from the number, if the number is larger
        -- than 2**31 (this would clear the most significant bit)
	if our_adler > 2147483647 then
		-- our adler has bit 31 set
                -- take countermeasures: substract 2**31
		our_adler := our_adler - 2147483648;
		signed := true;
	else
		our_adler := our_adler;
		signed := false;
	end if;

        -- Extract the 16 least significant bits
	s1 := bitand(our_adler,65535);
        -- Extract the 15 most significant bits after we ignore the most
        -- significant bit (2**31 - 2**16)
	s2 := bitand(our_adler,2147418112) / 65536;
	if signed then
                -- Add the sign bit back as 2**15
		s2 := s2 + 32768;
	end if;
	for n in 1..length(buf) loop
		currchar := ascii(substr(buf,n,1));
                -- 65521 is the highest prime under 0xffff
		s1 := mod((s1+currchar), 65521);
		s2 := mod((s2 + s1), 65521);
	end loop;
	return s2 * 65536 + s1;
end;
/
show errors
