#### SpookyHash
#### Copyright (c) 2023-2024, Remilia Scarlet
#### Copyright (c) 2015, Guillaume Voirin
#### BSD 3-Clause License
####
#### All rights reserved.
####
#### Redistribution and use in source and binary forms, with or without
#### modification, are permitted provided that the following conditions are met:
####
#### Redistributions of source code must retain the above copyright notice,
#### this list of conditions and the following disclaimer.
####
#### Redistributions in binary form must reproduce the above copyright
#### notice, this list of conditions and the following disclaimer in the
#### documentation and/or other materials provided with the distribution.
####
#### Neither the name of the copyright holder nor the names of its
#### contributors may be used to endorse or promote products derived from
#### this software without specific prior written permission.
####
#### THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#### AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#### IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#### ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#### LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#### CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#### SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#### INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#### CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#### ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#### POSSIBILITY OF SUCH DAMAGE.
####
#### SpookyHash Global Variables and Utility Macros/Methods
####
class RemiLib::Digest::SpookyHash
# The version of the algorithm that's supported.
VERSION = "1.0.7"
# :nodoc:
SPOOKYHASH_VARIABLES = 12
# :nodoc:
SPOOKYHASH_BLOCK_SIZE = SPOOKYHASH_VARIABLES * 8
# :nodoc:
SPOOKYHASH_BUFFER_SIZE = 2 * SPOOKYHASH_BLOCK_SIZE
# :nodoc:
SPOOKYHASH_CONSTANT = 0xDEADBEEFDEADBEEF_u64
# :nodoc:
alias PUInt8 = Pointer(UInt8)
# :nodoc:
alias PUInt64 = Pointer(UInt64)
# Ensures `val` is little-endian.
private macro little(val)
# At time of writing (6 May 2023), Crystal only seems to be on little-endian
# architectures, so this is rather a moot point. But it's here for future
# use as-needed.
{% if flag?(:aarch64) || flag?(:arm) || flag?(:i386) || flag?(:x86_64) %}
{{val}}
{% else %}
{% raise "Don't know the endianness of this architecture" %}
{% end %}
end
@[AlwaysInline]
protected def self.rotate(val : UInt64, by : Int) : UInt64
val.unsafe_shl(by) | (val.unsafe_shr(64 &- by))
end
protected def self.splitU128(num) : Tuple(UInt64, UInt64)
{
num.to_u64!,
((num & 0xFFFFFFFFFFFFFFFF0000000000000000_u128) >> 64).to_u64!
}
end
# :nodoc:
macro makeU128(low, high)
({{high}}.to_u128!.unsafe_shl(64) | {{low}})
end
end
|