Inspired by the recent addition of FNV hashing, I had a look at how hard it would be to add support for Jenkins's one-at-a-time hashing to ext/hash. The result is attached to this mail. I don't think I have karma for php-src, so given enough interest feel free to commit the patch.
- Martin
Index: php_hash.h =================================================================== --- php_hash.h (revision 296707) +++ php_hash.h (working copy) @@ -82,6 +82,7 @@ extern const php_hash_ops php_hash_salsa20_ops; extern const php_hash_ops php_hash_fnv132_ops; extern const php_hash_ops php_hash_fnv164_ops; +extern const php_hash_ops php_hash_joaat_ops; #define PHP_HASH_HAVAL_OPS(p,b) extern const php_hash_ops php_hash_##p##haval##b##_ops; Index: php_hash_joaat.h =================================================================== --- php_hash_joaat.h (revision 0) +++ php_hash_joaat.h (revision 0) @@ -0,0 +1,43 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2010 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | lice...@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Martin Jansen <m...@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id*/ + +#ifndef PHP_HASH_JOAAT_H +#define PHP_HASH_JOAAT_H + +typedef struct { + php_hash_uint32 state; +} PHP_JOAAT_CTX; + +PHP_HASH_API void PHP_JOAATInit(PHP_JOAAT_CTX *context); +PHP_HASH_API void PHP_JOAATUpdate(PHP_JOAAT_CTX *context, const unsigned char *input, unsigned int inputLen); +PHP_HASH_API void PHP_JOAATFinal(unsigned char digest[16], PHP_JOAAT_CTX * context); + +static php_hash_uint32 joaat_buf(void *buf, size_t len); + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ Index: tests/hash_algos.phpt =================================================================== --- tests/hash_algos.phpt (revision 296707) +++ tests/hash_algos.phpt (working copy) @@ -18,7 +18,7 @@ ===Done=== --EXPECTF-- *** Testing hash_algos() : basic functionality *** -array(42) { +array(45) { [0]=> string(3) "md2" [1]=> @@ -74,34 +74,40 @@ [26]=> string(7) "salsa20" [27]=> + string(6) "fnv132" + [28]=> + string(6) "fnv164" + [29]=> + string(5) "joaat" + [30]=> string(10) "haval128,3" - [28]=> + [31]=> string(10) "haval160,3" - [29]=> + [32]=> string(10) "haval192,3" - [30]=> + [33]=> string(10) "haval224,3" - [31]=> + [34]=> string(10) "haval256,3" - [32]=> + [35]=> string(10) "haval128,4" - [33]=> + [36]=> string(10) "haval160,4" - [34]=> + [37]=> string(10) "haval192,4" - [35]=> + [38]=> string(10) "haval224,4" - [36]=> + [39]=> string(10) "haval256,4" - [37]=> + [40]=> string(10) "haval128,5" - [38]=> + [41]=> string(10) "haval160,5" - [39]=> + [42]=> string(10) "haval192,5" - [40]=> + [43]=> string(10) "haval224,5" - [41]=> + [44]=> string(10) "haval256,5" } ===Done=== \ No newline at end of file Index: tests/joaat.phpt =================================================================== --- tests/joaat.phpt (revision 0) +++ tests/joaat.phpt (revision 0) @@ -0,0 +1,34 @@ +--TEST-- +Jenkins's one-at-a-time +--SKIPIF-- +<?php extension_loaded('hash') or die ('Skip - hash extension not available'); ?> +--FILE-- +<?php +$tests = array( + array("hello world", "3e4a5a57"), + array("", 0), + array("", "000000"), + array("a", "ca2e9442"), + array("aa", "7081738e"), +); + +$i = 0; +$pass = true; + +foreach ($tests as $test) { + ++$i; + + $result = hash("joaat", $test[0]); + if ($result != $test[1]) { + echo "Iteration " . $i . " failed - expected '" . $test[1] . "', got '" . $result . "' for '" . $test[1] . "'\n"; + + $pass = false; + } +} + +if($pass) { + echo "PASS"; +} +?> +--EXPECT-- +PASS Index: hash.c =================================================================== --- hash.c (revision 296707) +++ hash.c (working copy) @@ -79,6 +79,7 @@ {"FNV1A32", "fnv1a32", 30}, {"FNV164", "fnv164", 31}, {"FNV1A64", "fnv1a64", 32}, + {"JOAAT", "joaat", 33}, }; #endif @@ -847,6 +848,7 @@ php_hash_register_algo("salsa20", &php_hash_salsa20_ops); php_hash_register_algo("fnv132", &php_hash_fnv132_ops); php_hash_register_algo("fnv164", &php_hash_fnv164_ops); + php_hash_register_algo("joaat", &php_hash_joaat_ops); PHP_HASH_HAVAL_REGISTER(3,128); PHP_HASH_HAVAL_REGISTER(3,160); Index: hash_joaat.c =================================================================== --- hash_joaat.c (revision 0) +++ hash_joaat.c (revision 0) @@ -0,0 +1,100 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2010 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | lice...@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Martin Jansen <m...@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +/* Implements Jenkins's one-at-a-time hashing algorithm as presented on + * http://www.burtleburtle.net/bob/hash/doobs.html. + */ + +#include "php_hash.h" +#include "php_hash_joaat.h" + +const php_hash_ops php_hash_joaat_ops = { + (php_hash_init_func_t) PHP_JOAATInit, + (php_hash_update_func_t) PHP_JOAATUpdate, + (php_hash_final_func_t) PHP_JOAATFinal, + (php_hash_copy_func_t) php_hash_copy, + 4, + 4, + sizeof(PHP_JOAAT_CTX) +}; + +PHP_HASH_API void PHP_JOAATInit(PHP_JOAAT_CTX *context) +{ + context->state = 0; +} + +PHP_HASH_API void PHP_JOAATUpdate(PHP_JOAAT_CTX *context, const unsigned char *input, unsigned int inputLen) +{ + context->state = joaat_buf((void *)input, inputLen); +} + +PHP_HASH_API void PHP_JOAATFinal(unsigned char digest[4], PHP_JOAAT_CTX * context) +{ +#ifdef WORDS_BIGENDIAN + memcpy(digest, &context->state, 4); +#else + int i = 0; + unsigned char *c = (unsigned char *) &context->state; + + for (i = 0; i < 4; i++) { + digest[i] = c[3 - i]; + } +#endif + context->state = 0; +} + +/* + * joaat_buf - perform a Jenkins's one-at-a-time hash on a buffer + * + * input: + * buf - start of buffer to hash + * len - length of buffer in octets + * + * returns: + * 32 bit hash as a static hash type + */ +static php_hash_uint32 +joaat_buf(void *buf, size_t len) +{ + php_hash_uint32 hval; + size_t i; + unsigned char *input = (unsigned char *)buf; + + for (i = 0; i < len; i++) { + hval += input[i]; + hval += (hval << 10); + hval ^= (hval >> 6); + } + + hval += (hval << 3); + hval ^= (hval >> 11); + hval += (hval << 15); + + return hval; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ Index: config.m4 =================================================================== --- config.m4 (revision 296707) +++ config.m4 (working copy) @@ -27,11 +27,11 @@ EXT_HASH_SOURCES="hash.c hash_md.c hash_sha.c hash_ripemd.c hash_haval.c \ hash_tiger.c hash_gost.c hash_snefru.c hash_whirlpool.c hash_adler32.c \ - hash_crc32.c hash_salsa.c hash_fnv.c" + hash_crc32.c hash_salsa.c hash_fnv.c hash_joaat.c" EXT_HASH_HEADERS="php_hash.h php_hash_md.h php_hash_sha.h php_hash_ripemd.h \ php_hash_haval.h php_hash_tiger.h php_hash_gost.h php_hash_snefru.h \ php_hash_whirlpool.h php_hash_adler32.h php_hash_crc32.h php_hash_salsa.h \ - php_hash_fnv.h php_hash_types.h" + php_hash_fnv.h php_hash_joaat.h php_hash_types.h" PHP_NEW_EXTENSION(hash, $EXT_HASH_SOURCES, $ext_shared) ifdef([PHP_INSTALL_HEADERS], [
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php