InfraRuby Vision delivers solutions for mobile and web applications.
You can try InfraRuby live in your browser!
Try the InfraRuby statically typed Ruby compiler live in your browser. Try our examples or write your own code.
Follow @InfraRuby on Twitter for news and updates.

SipHash ✦ Examples

InfraRuby is a compiler and runtime for statically typed Ruby. You can use InfraRuby for your own projects with our free download!

coding style

The InfraRuby compiler supports many coding styles. In particular, you may use either spaces or tabs for indentation and you may omit the return keyword where applicable.

For more information:

This example implements the SipHash function.

SipHash

## <>
module SipHash
	class << self
		## int64, int64, int64, int64 -> [int64, int64, int64, int64]
		def __round(v0, v1, v2, v3)
			v0 += v1
			v2 += v3
			v1 = v1.rol(13)
			v3 = v3.rol(16)
			v1 ^= v0
			v3 ^= v2
			v0 = v0.rol(32)
			v2 += v1
			v0 += v3
			v1 = v1.rol(17)
			v3 = v3.rol(21)
			v1 ^= v2
			v3 ^= v0
			v2 = v2.rol(32)
			return [v0, v1, v2, v3]
		end

		## int64, int64, byte[] -> int64
		def digest_as_int64(k0, k1, m)
			v0 = k0 ^ 0x736F6D6570736575
			v1 = k1 ^ 0x646F72616E646F6D
			v2 = k0 ^ 0x6C7967656E657261
			v3 = k1 ^ 0x7465646279746573
			n = m.length & ~7.i32
			i = 0.i32
			while i < n
				w = 0.i64
				j = 0.i32
				while j < 64
					w |= (m[i] & 0xFF).to_int64 << j
					i += 1
					j += 8
				end
				v3 ^= w
				v0, v1, v2, v3 = __round(v0, v1, v2, v3)
				v0, v1, v2, v3 = __round(v0, v1, v2, v3)
				v0 ^= w
			end
			w = 0.i64
			j = 0.i32
			while i < m.length
				w |= (m[i] & 0xFF).to_int64 << j
				i += 1
				j += 8
			end
			w |= m.length.to_int64 << 070
			v3 ^= w
			v0, v1, v2, v3 = __round(v0, v1, v2, v3)
			v0, v1, v2, v3 = __round(v0, v1, v2, v3)
			v0 ^= w
			v2 ^= 0xFF
			v0, v1, v2, v3 = __round(v0, v1, v2, v3)
			v0, v1, v2, v3 = __round(v0, v1, v2, v3)
			v0, v1, v2, v3 = __round(v0, v1, v2, v3)
			v0, v1, v2, v3 = __round(v0, v1, v2, v3)
			return v0 ^ v1 ^ v2 ^ v3
		end

		## String, String -> Integer
		def digest(k, s)
			m = k.to_j_bytes_unsafe
			n = m.length
			if n != 020
				raise ArgumentError, "key must be 16 bytes"
			end
			k1 = 0.i64
			while n > 8
				n -= 1
				k1 <<= 8
				k1 |= (m[n] & 0xFF).to_int64
			end
			k0 = 0.i64
			while n > 0
				n -= 1
				k0 <<= 8
				k0 |= (m[n] & 0xFF).to_int64
			end
			v = digest_as_int64(k0, k1, s.to_j_bytes_unsafe)
			if v < 0
				return v.new_integer & 0xFFFFFFFFFFFFFFFF
			end
			return v.new_integer
		end
	end
end
Follow @InfraRuby on Twitter
Copyright © 2011-2017 InfraRuby Vision Limited