2014-09-24 19:16:16 +00:00
/ * tigersum - a command line utility to calculate the tiger hash from input .
Copyright ( C ) 2014 Michele "King_DuckZ" Santullo
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU 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 General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* /
2014-09-24 18:36:53 +00:00
import std.stdio ;
import std.string ;
import std.array , std . range ;
import std.algorithm ;
private extern ( C ) void tiger ( char * parMessage , ulong parLength , out ulong [ 3 ] parOut , char parPadding ) ;
private extern ( C ) void tiger_init ( out ulong [ 3 ] parOut ) ;
private extern ( C ) void tiger_chunk ( char * parMessage , ulong parLength , out ulong [ 3 ] parOut ) ;
private extern ( C ) void tiger_last_chunk ( char * parMessage , ulong parBuffLength , ulong parTotalLength , out ulong [ 3 ] parOut , char parPadding ) ;
private ulong swapLong ( ulong parNum ) {
parNum = ( parNum & 0x00000000FFFFFFFF ) < < 32 | ( parNum & 0xFFFFFFFF00000000 ) > > 32 ;
parNum = ( parNum & 0x0000FFFF0000FFFF ) < < 16 | ( parNum & 0xFFFF0000FFFF0000 ) > > 16 ;
parNum = ( parNum & 0x00FF00FF00FF00FF ) < < 8 | ( parNum & 0xFF00FF00FF00FF00 ) > > 8 ;
return parNum ;
}
public ulong [ 3 ] getTiger ( in string parData , bool parV2 ) {
char [ ] unaligned = new char [ parData . length + ulong . alignof - 1 ] ;
size_t offset = ( ( cast ( size_t ) unaligned . ptr + ( ulong . alignof - 1 ) ) & ~ cast ( size_t ) ( ulong . alignof - 1 ) ) - cast ( size_t ) unaligned . ptr ;
assert ( offset > = 0 & & offset < ulong . alignof ) ;
assert ( offset + parData . length < = unaligned . length ) ;
char padding = ( parV2 ? 0x80 : 0x01 ) ;
char [ ] aligned = unaligned [ offset . . offset + parData . length ] ;
aligned [ ] = parData [ ] ;
assert ( ( cast ( size_t ) aligned . ptr & cast ( size_t ) ( ulong . alignof - 1 ) ) = = 0 ) ;
ulong [ 3 ] retval ;
tiger ( aligned . ptr , aligned . length , retval , padding ) ;
return retval ;
}
public ulong [ 3 ] getTiger ( ref File parData , bool parV2 ) {
const auto buff_length = 64 * 128 ;
char [ ] unaligned = new char [ buff_length + ulong . alignof - 1 ] ;
size_t offset = ( ( cast ( size_t ) unaligned . ptr + ( ulong . alignof - 1 ) ) & ~ cast ( size_t ) ( ulong . alignof - 1 ) ) - cast ( size_t ) unaligned . ptr ;
assert ( offset > = 0 & & offset < ulong . alignof ) ;
assert ( offset + buff_length < = unaligned . length ) ;
char [ ] aligned = unaligned [ offset . . buff_length ] ;
assert ( aligned . length = = buff_length ) ;
ulong [ 3 ] retval ;
auto data_left = parData . size ;
tiger_init ( retval ) ;
while ( data_left > = buff_length ) {
parData . rawRead ( aligned ) ;
tiger_chunk ( aligned . ptr , buff_length , retval ) ;
data_left - = buff_length ;
}
const char padding = ( parV2 ? 0x80 : 0x01 ) ;
if ( data_left ) {
parData . rawRead ( aligned [ 0 . . data_left ] ) ;
const ulong proc_length = data_left & ~ 0x3f UL ;
tiger_chunk ( aligned . ptr , proc_length , retval ) ;
tiger_last_chunk ( aligned . ptr + proc_length , data_left - proc_length , parData . size , retval , padding ) ;
}
else {
tiger_last_chunk ( null , 0 , parData . size , retval , padding ) ;
}
return retval ;
}
public string tigerToString ( in ulong [ 3 ] parTiger ) {
return format ( "%016x%016x%016x" , swapLong ( parTiger [ 0 ] ) , swapLong ( parTiger [ 1 ] ) , swapLong ( parTiger [ 2 ] ) ) ;
}
unittest {
assert ( "67e6ae8e9e968999f70a23e72aeaa9251cbc7c78a7916636" = = tigerToString ( getTiger ( "a" , true ) ) ) ;
assert ( "f68d7bc5af4b43a06e048d7829560d4a9415658bb0b1f3bf" = = tigerToString ( getTiger ( "abc" , true ) ) ) ;
assert ( "e29419a1b5fa259de8005e7de75078ea81a542ef2552462d" = = tigerToString ( getTiger ( "message digest" , true ) ) ) ;
assert ( "f5b6b6a78c405c8547e91cd8624cb8be83fc804a474488fd" = = tigerToString ( getTiger ( "abcdefghijklmnopqrstuvwxyz" , true ) ) ) ;
assert ( "a6737f3997e8fbb63d20d2df88f86376b5fe2d5ce36646a9" = = tigerToString ( getTiger ( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" , true ) ) ) ;
assert ( "ea9ab6228cee7b51b77544fca6066c8cbb5bbae6319505cd" = = tigerToString ( getTiger ( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" , true ) ) ) ;
assert ( "d85278115329ebaa0eec85ecdc5396fda8aa3a5820942fff" = = tigerToString ( getTiger ( replicate ( "1234567890" , 8 ) , true ) ) ) ;
assert ( "e068281f060f551628cc5715b9d0226796914d45f7717cf4" = = tigerToString ( getTiger ( replicate ( "a" , 1000000 ) , true ) ) ) ;
assert ( "2aab1484e8c158f2bfb8c5ff41b57a525129131c957b5f93" = = tigerToString ( getTiger ( "abc" , false ) ) ) ;
assert ( "dd00230799f5009fec6debc838bb6a27df2b9d6f110c7937" = = tigerToString ( getTiger ( "Tiger" , false ) ) ) ;
assert ( "f71c8583902afb879edfe610f82c0d4786a3a534504486b5" = = tigerToString ( getTiger ( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-" , false ) ) ) ;
assert ( "48ceeb6308b87d46e95d656112cdf18d97915f9765658957" = = tigerToString ( getTiger ( "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789" , false ) ) ) ;
assert ( "8a866829040a410c729ad23f5ada711603b3cdd357e4c15e" = = tigerToString ( getTiger ( "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham" , false ) ) ) ;
assert ( "ce55a6afd591f5ebac547ff84f89227f9331dab0b611c889" = = tigerToString ( getTiger ( "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge." , false ) ) ) ;
assert ( "631abdd103eb9a3d245b6dfd4d77b257fc7439501d1568dd" = = tigerToString ( getTiger ( "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996." , false ) ) ) ;
assert ( "c54034e5b43eb8005848a7e0ae6aac76e4ff590ae715fd25" = = tigerToString ( getTiger ( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-" , false ) ) ) ;
}