'      Title: SuperFastHash
'   FileName: superfasthash.bac
'     Author: Peter Fedorow (BaCon version)
'  Copyright: Copyright 2012 Peter Fedorow.  Derived from original C code by Paul Hsieh.
'    License: This program is free software: you can redistribute it and/or modify
'             it under the terms of the GNU Lesser General Public License as published by
'             the Free Software Foundation, either version 3 of the License, or
'             (at your option) any later version.
'
'             This program is distributed in the hope that it will be useful,
'             but WITHOUT ANY WARRANTY; without even the implied warranty of
'             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'             GNU General Public License for more details.
'
'             You should have received a copy of the GNU Lesser General Public License
'             along with this program.  If not, see <http://www.gnu.org/licenses/lgpl.txt>.
'    Started: 2006Jul08Sat
'Last Change: 2012Mar15Thu
'    History: 2012Mar09Fri PF - Started port to BaCon from my PowerBASIC version.
'    History: 2012Mar14Wed PF - Port completed, same results compiled for 32 and 64bit.
'    History: 2012Mar15Thu PF - Minor code cleanup.
'       Note: SuperFastHash is the fastest hashing algorithm I know of that is avalanching.
'             Developed for BaCon 1.0 Build 25.
'             More information available the algorithm is available at http://www.azillionmonkeys.com/qed/hash.html
'      Usage: Place a line in your program: INCLUDE "lib-superfasthash.bac"

'----------------------------------------------------------------------------
FUNCTION SuperFastHash (NUMBER Buffer, NUMBER BufferSize)

	LOCAL Result TYPE unsigned int
	LOCAL Remainder TYPE unsigned int
	LOCAL Tmp TYPE unsigned int
	LOCAL TextPointer TYPE unsigned int
	LOCAL LenText TYPE unsigned int
	LOCAL BufferPointer


	Result = 0

	LenText = BufferSize
	IF LenText > 0 THEN

		Result = LenText

		Remainder = LenText & 3

		LenText = LenText >> 2

		BufferPointer = Buffer

		'Main Hash Loop
		'--------------
		OPTION MEMTYPE short
		WHILE LenText > 0
			LenText = LenText - 1
			Result = Result + PEEK(BufferPointer)
			BufferPointer = BufferPointer + 2
			Tmp = PEEK(BufferPointer)
			Tmp = (Tmp << 11) ^ Result
			Result = (Result << 16) ^ Tmp
			BufferPointer = BufferPointer + 2
			Result = Result + (Result >> 11)

		WEND


		'Handle End Cases
		'----------------
		SELECT Remainder
		  CASE 3
		    Result = Result + PEEK(BufferPointer)
		    Result = (Result << 16) ^ Result
		    BufferPointer = BufferPointer + 2
		    OPTION MEMTYPE char
		    Tmp = PEEK(BufferPointer)
		    Result = Result ^ (Tmp << 18)
		    Result = Result + (Result >> 11)

		  CASE 2
		  	Result = Result + PEEK(BufferPointer)
		  	Result = (Result << 11) ^ Result
		  	Result = Result + (Result >> 17)

		  CASE 1
		    OPTION MEMTYPE char
		    Result = Result + PEEK(BufferPointer)
		    Result = Result ^ (Result << 10)
		    Result = Result + (Result >> 1)

		END SELECT


		'Force Avalanching of Final 127 Bits
		'-----------------------------------

		'Hsieh's improved avalanche design.
		Result = Result ^ (Result << 3)
		Result = Result + (Result >> 5)
		Result = Result ^ (Result << 4)
		Result = Result + (Result >> 17)
		Result = Result ^ (Result << 25)
		Result = Result + (Result >> 6)

	END IF


	RETURN Result

END FUNCTION


'----------------------------------------------------------------------------
FUNCTION SuperFastHashString (STRING Text$)

  LOCAL TextLen
  LOCAL TextPointer
  LOCAL TextAddress
  LOCAL Result TYPE unsigned int


  TextLen = LEN(Text$)
  TextPointer = ADDRESS(Text$)

  OPTION MEMTYPE long
  TextAddress = PEEK(TextPointer)

  Result = SuperFastHash(TextAddress, TextLen)


  RETURN Result

END FUNCTION