2014-09-19 17:19:25 +01:00
import std.stdio ;
2014-09-24 10:09:35 +02:00
import std.string ;
import std.array , std . range ;
import std.file ;
import std.algorithm ;
2014-09-19 17:19:25 +01:00
extern ( C ) void tiger ( char * parMessage , ulong parLength , out ulong [ 3 ] parOut , char parPadding ) ;
2014-09-24 10:09:35 +02:00
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 ;
}
2014-09-19 17:19:25 +01:00
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 ;
}
2014-09-24 10:09:35 +02:00
ulong [ 3 ] getTiger ( ref File parData , bool parV2 ) {
const auto buff_length = 8192 ;
ubyte [ ] unaligned = new ubyte [ 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 ) ;
const char padding = ( parV2 ? 0x80 : 0x01 ) ;
assert ( offset + buff_length < = unaligned . length ) ;
ubyte [ ] aligned = unaligned [ offset . . buff_length ] ;
assert ( aligned . length = = buff_length ) ;
ulong [ 3 ] retval ;
foreach ( ubyte [ ] buff ; parData . byChunk ( aligned ) ) {
assert ( ( cast ( size_t ) buff . ptr & cast ( size_t ) ( ulong . alignof - 1 ) ) = = 0 ) ;
tiger ( ( cast ( char [ ] ) buff ) . ptr , buff . length , retval , padding ) ;
}
return retval ;
}
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 ) ) ) ;
2014-09-19 17:19:25 +01:00
}
void main ( string [ ] parArgs ) {
2014-09-24 10:09:35 +02:00
const auto cwd = getcwd ( ) ;
const auto working_dir = cwd ~ ( cwd [ $ - 1 ] = = '/' ? "" : "/" ) ;
foreach ( arg ; parArgs [ 1 . . $ ] ) {
const auto curr_path = working_dir ~ arg ;
File curr_file = File ( curr_path , "rb" ) ;
if ( ! isDir ( curr_path ) ) {
writefln ( "%s %s" , tigerToString ( getTiger ( curr_file , true ) ) , arg ) ;
}
else {
writefln ( "tigersum: %s: is a directory" , arg ) ;
}
}
2014-09-19 17:19:25 +01:00
}