diff options
author | Mike Buland <eichlan@xagasoft.com> | 2009-02-19 23:44:57 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2009-02-19 23:44:57 +0000 |
commit | 4309066dff46f52690998bbd1f60ec8b1631f142 (patch) | |
tree | 07b6092622c909351f20590e7ee96d07f5b2d010 /src | |
parent | 3f958097632256329cdbaf2219e2ba15325e9c52 (diff) | |
download | libbu++-4309066dff46f52690998bbd1f60ec8b1631f142.tar.gz libbu++-4309066dff46f52690998bbd1f60ec8b1631f142.tar.bz2 libbu++-4309066dff46f52690998bbd1f60ec8b1631f142.tar.xz libbu++-4309066dff46f52690998bbd1f60ec8b1631f142.zip |
We have the new Bu::CryptoHash base class and Bu::Md5 is here and ready
to rock. sha1 is still only a shell, I dunno if/when I'm going to implement
that one.
So far Bu::Md5 is 100% compatible with md5sum in all tests performed so far, in
fact the test program's output is compatible with md5sum in every way (and it's
so cute and little too!)
Oh, minor update for stdstream and the formatter, they can handle more handy
types now.
Diffstat (limited to '')
-rw-r--r-- | src/cryptohash.cpp | 15 | ||||
-rw-r--r-- | src/cryptohash.h | 22 | ||||
-rw-r--r-- | src/formatter.cpp | 6 | ||||
-rw-r--r-- | src/formatter.h | 1 | ||||
-rw-r--r-- | src/md5.cpp | 191 | ||||
-rw-r--r-- | src/md5.h | 40 | ||||
-rw-r--r-- | src/sha1.cpp | 161 | ||||
-rw-r--r-- | src/sha1.h | 42 | ||||
-rw-r--r-- | src/tests/md5.cpp | 27 | ||||
-rw-r--r-- | src/tests/stdstream.cpp | 4 |
10 files changed, 507 insertions, 2 deletions
diff --git a/src/cryptohash.cpp b/src/cryptohash.cpp new file mode 100644 index 0000000..0fa2a25 --- /dev/null +++ b/src/cryptohash.cpp | |||
@@ -0,0 +1,15 @@ | |||
1 | #include "bu/cryptohash.h" | ||
2 | |||
3 | Bu::CryptoHash::CryptoHash() | ||
4 | { | ||
5 | } | ||
6 | |||
7 | Bu::CryptoHash::~CryptoHash() | ||
8 | { | ||
9 | } | ||
10 | |||
11 | void Bu::CryptoHash::addData( const Bu::FString &sData ) | ||
12 | { | ||
13 | addData( sData.getStr(), sData.getSize() ); | ||
14 | } | ||
15 | |||
diff --git a/src/cryptohash.h b/src/cryptohash.h new file mode 100644 index 0000000..01d4634 --- /dev/null +++ b/src/cryptohash.h | |||
@@ -0,0 +1,22 @@ | |||
1 | #ifndef BU_CRYPTO_HASH_H | ||
2 | #define BU_CRYPTO_HASH_H | ||
3 | |||
4 | #include "bu/fstring.h" | ||
5 | |||
6 | namespace Bu | ||
7 | { | ||
8 | class CryptoHash | ||
9 | { | ||
10 | public: | ||
11 | CryptoHash(); | ||
12 | virtual ~CryptoHash(); | ||
13 | |||
14 | virtual void reset() = 0; | ||
15 | virtual void setSalt( const Bu::FString &sSalt ) = 0; | ||
16 | virtual void addData( const char *sData, int iSize ) = 0; | ||
17 | virtual void addData( const Bu::FString &sData ); | ||
18 | virtual FString getResult() = 0; | ||
19 | }; | ||
20 | }; | ||
21 | |||
22 | #endif | ||
diff --git a/src/formatter.cpp b/src/formatter.cpp index 1ec3c39..36e49c8 100644 --- a/src/formatter.cpp +++ b/src/formatter.cpp | |||
@@ -159,6 +159,12 @@ Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const char *sStr ) | |||
159 | return rOut; | 159 | return rOut; |
160 | } | 160 | } |
161 | 161 | ||
162 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, char *sStr ) | ||
163 | { | ||
164 | rOut.writeAligned( sStr, strlen( sStr ) ); | ||
165 | return rOut; | ||
166 | } | ||
167 | |||
162 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const Bu::FString &sStr ) | 168 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const Bu::FString &sStr ) |
163 | { | 169 | { |
164 | rOut.writeAligned( sStr ); | 170 | rOut.writeAligned( sStr ); |
diff --git a/src/formatter.h b/src/formatter.h index 4bab505..d9066cb 100644 --- a/src/formatter.h +++ b/src/formatter.h | |||
@@ -185,6 +185,7 @@ namespace Bu | |||
185 | Formatter &operator<<( Formatter &rOut, const Formatter::Fmt &f ); | 185 | Formatter &operator<<( Formatter &rOut, const Formatter::Fmt &f ); |
186 | Formatter &operator<<( Formatter &rOut, Formatter::Special s ); | 186 | Formatter &operator<<( Formatter &rOut, Formatter::Special s ); |
187 | Formatter &operator<<( Formatter &rOut, const char *sStr ); | 187 | Formatter &operator<<( Formatter &rOut, const char *sStr ); |
188 | Formatter &operator<<( Formatter &rOut, char *sStr ); | ||
188 | Formatter &operator<<( Formatter &rOut, const Bu::FString &sStr ); | 189 | Formatter &operator<<( Formatter &rOut, const Bu::FString &sStr ); |
189 | Formatter &operator<<( Formatter &rOut, signed char c ); | 190 | Formatter &operator<<( Formatter &rOut, signed char c ); |
190 | Formatter &operator<<( Formatter &rOut, char c ); | 191 | Formatter &operator<<( Formatter &rOut, char c ); |
diff --git a/src/md5.cpp b/src/md5.cpp new file mode 100644 index 0000000..aa965ed --- /dev/null +++ b/src/md5.cpp | |||
@@ -0,0 +1,191 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include "md5.h" | ||
5 | |||
6 | // This performs a wrapping bitwise shift, kinda' fun! | ||
7 | |||
8 | #define bit_roll( num, cnt ) \ | ||
9 | (((num) << (cnt)) | (((num) >> (32 - (cnt))) & ~(-1<<(cnt)))) | ||
10 | |||
11 | //#define md5_cmn( q, a, b, x, s, t ) (bit_roll((a + q + x + t), s) + b) | ||
12 | |||
13 | // The following are handy wrappers for the cmn function | ||
14 | #define md5_ff( a, b, c, d, x, s, t ) \ | ||
15 | (md5_cmn((b & c) | ((~b) & d), a, b, x, s, t)) | ||
16 | |||
17 | #define md5_gg( a, b, c, d, x, s, t ) \ | ||
18 | (md5_cmn((b & d) | (c & (~d)), a, b, x, s, t)) | ||
19 | |||
20 | #define md5_hh( a, b, c, d, x, s, t ) \ | ||
21 | (md5_cmn(b ^ c ^ d, a, b, x, s, t)) | ||
22 | |||
23 | #define md5_ii( a, b, c, d, x, s, t ) \ | ||
24 | (md5_cmn(c ^ (b | (~d)), a, b, x, s, t)) | ||
25 | |||
26 | inline long md5_cmn( long q, long a, long b, long x, long s, long t ) | ||
27 | { | ||
28 | return bit_roll((a + q + x + t), s) + b; | ||
29 | } | ||
30 | |||
31 | Bu::Md5::Md5() | ||
32 | { | ||
33 | reset(); | ||
34 | } | ||
35 | |||
36 | Bu::Md5::~Md5() | ||
37 | { | ||
38 | } | ||
39 | |||
40 | void Bu::Md5::reset() | ||
41 | { | ||
42 | // These are the magic seed numbers... | ||
43 | |||
44 | sum[0] = 1732584193; | ||
45 | sum[1] = -271733879; | ||
46 | sum[2] = -1732584194; | ||
47 | sum[3] = 271733878; | ||
48 | |||
49 | iBytes = 0; | ||
50 | memset( inbuf, 0, 4*16 ); | ||
51 | iFill = 0; | ||
52 | } | ||
53 | |||
54 | void Bu::Md5::setSalt( const Bu::FString & /*sSalt*/ ) | ||
55 | { | ||
56 | } | ||
57 | |||
58 | void Bu::Md5::addData( const char *sData, int iSize ) | ||
59 | { | ||
60 | int iInPos = 0; | ||
61 | for(;;) | ||
62 | { | ||
63 | for( ; iFill < 16*4 && iInPos < iSize; iFill++, iInPos++ ) | ||
64 | { | ||
65 | inbuf[iFill>>2] |= ((long)sData[iInPos]) << ((iFill*8)%32); | ||
66 | } | ||
67 | if( iFill < 16*4 ) | ||
68 | break; | ||
69 | compBlock( inbuf, sum ); | ||
70 | memset( inbuf, 0, 4*16 ); | ||
71 | iFill = 0; | ||
72 | } | ||
73 | iBytes += iSize; | ||
74 | } | ||
75 | |||
76 | Bu::FString Bu::Md5::getResult() | ||
77 | { | ||
78 | static const char hex_tab[] = {"0123456789abcdef"}; | ||
79 | char str[33]; | ||
80 | |||
81 | long lsum[4]; | ||
82 | memcpy( lsum, sum, 4*4 ); | ||
83 | long lbuf[16]; | ||
84 | memcpy( lbuf, inbuf, 4*16 ); | ||
85 | |||
86 | lbuf[iFill>>2] |= 0x80 << ((iFill*8)%32); | ||
87 | uint64_t iBits = iBytes*8; | ||
88 | if( iBytes > 0 && iFill>>2 >= 14 ) | ||
89 | { | ||
90 | compBlock( lbuf, lsum ); | ||
91 | memset( lbuf, 0, 4*16 ); | ||
92 | memcpy( lbuf+14, &iBits, 8 ); | ||
93 | compBlock( lbuf, lsum ); | ||
94 | } | ||
95 | else | ||
96 | { | ||
97 | memcpy( lbuf+14, &iBits, 8 ); | ||
98 | compBlock( lbuf, lsum ); | ||
99 | } | ||
100 | |||
101 | int k = 0; | ||
102 | for( int i = 0; i < 16; i++ ) | ||
103 | { | ||
104 | str[k++] = hex_tab[(lsum[i>>2] >> ((i%4)*8+4)) & 0xF]; | ||
105 | str[k++] = hex_tab[(lsum[i>>2] >> ((i%4)*8 )) & 0xF]; | ||
106 | } | ||
107 | |||
108 | return Bu::FString( str, 32 ); | ||
109 | } | ||
110 | |||
111 | void Bu::Md5::compBlock( long *x, long *lsum ) | ||
112 | { | ||
113 | long a = lsum[0]; | ||
114 | long b = lsum[1]; | ||
115 | long c = lsum[2]; | ||
116 | long d = lsum[3]; | ||
117 | |||
118 | a = md5_ff(a, b, c, d, x[ 0], 7 , -680876936); | ||
119 | d = md5_ff(d, a, b, c, x[ 1], 12, -389564586); | ||
120 | c = md5_ff(c, d, a, b, x[ 2], 17, 606105819); | ||
121 | b = md5_ff(b, c, d, a, x[ 3], 22, -1044525330); | ||
122 | a = md5_ff(a, b, c, d, x[ 4], 7 , -176418897); | ||
123 | d = md5_ff(d, a, b, c, x[ 5], 12, 1200080426); | ||
124 | c = md5_ff(c, d, a, b, x[ 6], 17, -1473231341); | ||
125 | b = md5_ff(b, c, d, a, x[ 7], 22, -45705983); | ||
126 | a = md5_ff(a, b, c, d, x[ 8], 7 , 1770035416); | ||
127 | d = md5_ff(d, a, b, c, x[ 9], 12, -1958414417); | ||
128 | c = md5_ff(c, d, a, b, x[10], 17, -42063); | ||
129 | b = md5_ff(b, c, d, a, x[11], 22, -1990404162); | ||
130 | a = md5_ff(a, b, c, d, x[12], 7 , 1804603682); | ||
131 | d = md5_ff(d, a, b, c, x[13], 12, -40341101); | ||
132 | c = md5_ff(c, d, a, b, x[14], 17, -1502002290); | ||
133 | b = md5_ff(b, c, d, a, x[15], 22, 1236535329); | ||
134 | |||
135 | a = md5_gg(a, b, c, d, x[ 1], 5 , -165796510); | ||
136 | d = md5_gg(d, a, b, c, x[ 6], 9 , -1069501632); | ||
137 | c = md5_gg(c, d, a, b, x[11], 14, 643717713); | ||
138 | b = md5_gg(b, c, d, a, x[ 0], 20, -373897302); | ||
139 | a = md5_gg(a, b, c, d, x[ 5], 5 , -701558691); | ||
140 | d = md5_gg(d, a, b, c, x[10], 9 , 38016083); | ||
141 | c = md5_gg(c, d, a, b, x[15], 14, -660478335); | ||
142 | b = md5_gg(b, c, d, a, x[ 4], 20, -405537848); | ||
143 | a = md5_gg(a, b, c, d, x[ 9], 5 , 568446438); | ||
144 | d = md5_gg(d, a, b, c, x[14], 9 , -1019803690); | ||
145 | c = md5_gg(c, d, a, b, x[ 3], 14, -187363961); | ||
146 | b = md5_gg(b, c, d, a, x[ 8], 20, 1163531501); | ||
147 | a = md5_gg(a, b, c, d, x[13], 5 , -1444681467); | ||
148 | d = md5_gg(d, a, b, c, x[ 2], 9 , -51403784); | ||
149 | c = md5_gg(c, d, a, b, x[ 7], 14, 1735328473); | ||
150 | b = md5_gg(b, c, d, a, x[12], 20, -1926607734); | ||
151 | |||
152 | a = md5_hh(a, b, c, d, x[ 5], 4 , -378558); | ||
153 | d = md5_hh(d, a, b, c, x[ 8], 11, -2022574463); | ||
154 | c = md5_hh(c, d, a, b, x[11], 16, 1839030562); | ||
155 | b = md5_hh(b, c, d, a, x[14], 23, -35309556); | ||
156 | a = md5_hh(a, b, c, d, x[ 1], 4 , -1530992060); | ||
157 | d = md5_hh(d, a, b, c, x[ 4], 11, 1272893353); | ||
158 | c = md5_hh(c, d, a, b, x[ 7], 16, -155497632); | ||
159 | b = md5_hh(b, c, d, a, x[10], 23, -1094730640); | ||
160 | a = md5_hh(a, b, c, d, x[13], 4 , 681279174); | ||
161 | d = md5_hh(d, a, b, c, x[ 0], 11, -358537222); | ||
162 | c = md5_hh(c, d, a, b, x[ 3], 16, -722521979); | ||
163 | b = md5_hh(b, c, d, a, x[ 6], 23, 76029189); | ||
164 | a = md5_hh(a, b, c, d, x[ 9], 4 , -640364487); | ||
165 | d = md5_hh(d, a, b, c, x[12], 11, -421815835); | ||
166 | c = md5_hh(c, d, a, b, x[15], 16, 530742520); | ||
167 | b = md5_hh(b, c, d, a, x[ 2], 23, -995338651); | ||
168 | |||
169 | a = md5_ii(a, b, c, d, x[ 0], 6 , -198630844); | ||
170 | d = md5_ii(d, a, b, c, x[ 7], 10, 1126891415); | ||
171 | c = md5_ii(c, d, a, b, x[14], 15, -1416354905); | ||
172 | b = md5_ii(b, c, d, a, x[ 5], 21, -57434055); | ||
173 | a = md5_ii(a, b, c, d, x[12], 6 , 1700485571); | ||
174 | d = md5_ii(d, a, b, c, x[ 3], 10, -1894986606); | ||
175 | c = md5_ii(c, d, a, b, x[10], 15, -1051523); | ||
176 | b = md5_ii(b, c, d, a, x[ 1], 21, -2054922799); | ||
177 | a = md5_ii(a, b, c, d, x[ 8], 6 , 1873313359); | ||
178 | d = md5_ii(d, a, b, c, x[15], 10, -30611744); | ||
179 | c = md5_ii(c, d, a, b, x[ 6], 15, -1560198380); | ||
180 | b = md5_ii(b, c, d, a, x[13], 21, 1309151649); | ||
181 | a = md5_ii(a, b, c, d, x[ 4], 6 , -145523070); | ||
182 | d = md5_ii(d, a, b, c, x[11], 10, -1120210379); | ||
183 | c = md5_ii(c, d, a, b, x[ 2], 15, 718787259); | ||
184 | b = md5_ii(b, c, d, a, x[ 9], 21, -343485551); | ||
185 | |||
186 | lsum[0] = a + lsum[0]; | ||
187 | lsum[1] = b + lsum[1]; | ||
188 | lsum[2] = c + lsum[2]; | ||
189 | lsum[3] = d + lsum[3]; | ||
190 | } | ||
191 | |||
diff --git a/src/md5.h b/src/md5.h new file mode 100644 index 0000000..c548041 --- /dev/null +++ b/src/md5.h | |||
@@ -0,0 +1,40 @@ | |||
1 | #ifndef BU_MD5_H | ||
2 | #define BU_MD5_H | ||
3 | |||
4 | #include "bu/cryptohash.h" | ||
5 | |||
6 | namespace Bu | ||
7 | { | ||
8 | /** | ||
9 | * Class for easily calculating MD5 sums of just about any data. | ||
10 | *@author Mike Buland | ||
11 | */ | ||
12 | class Md5 : public Bu::CryptoHash | ||
13 | { | ||
14 | public: | ||
15 | /** Build an MD5 sum builder. */ | ||
16 | Md5(); | ||
17 | |||
18 | /** Deconstruct */ | ||
19 | virtual ~Md5(); | ||
20 | |||
21 | virtual void reset(); | ||
22 | virtual void setSalt( const Bu::FString &sSalt ); | ||
23 | virtual void addData( const char *sData, int iSize ); | ||
24 | using Bu::CryptoHash::addData; | ||
25 | virtual FString getResult(); | ||
26 | |||
27 | private: | ||
28 | /** | ||
29 | * Compute one block of input data. | ||
30 | */ | ||
31 | void compBlock( long *x, long *lsum ); | ||
32 | |||
33 | long inbuf[16]; | ||
34 | long iFill; | ||
35 | long sum[4]; | ||
36 | uint64_t iBytes; | ||
37 | }; | ||
38 | }; | ||
39 | |||
40 | #endif | ||
diff --git a/src/sha1.cpp b/src/sha1.cpp new file mode 100644 index 0000000..8270c3b --- /dev/null +++ b/src/sha1.cpp | |||
@@ -0,0 +1,161 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h> | ||
3 | #include <stdlib.h> | ||
4 | |||
5 | #include "sha1.h" | ||
6 | |||
7 | Sha1::Sha1() : | ||
8 | H0( 0x67452301 ), | ||
9 | H1( 0xefcdab89 ), | ||
10 | H2( 0x98badcfe ), | ||
11 | H3( 0x10325476 ), | ||
12 | H4( 0xc3d2e1f0 ), | ||
13 | unprocessedBytes( 0 ), | ||
14 | size( 0 ) | ||
15 | { | ||
16 | } | ||
17 | |||
18 | Sha1::~Sha1() | ||
19 | { | ||
20 | } | ||
21 | |||
22 | void Sha1::process() | ||
23 | { | ||
24 | int t; | ||
25 | uint32_t a, b, c, d, e, K, f, W[80]; | ||
26 | |||
27 | // starting values | ||
28 | a = H0; | ||
29 | b = H1; | ||
30 | c = H2; | ||
31 | d = H3; | ||
32 | e = H4; | ||
33 | |||
34 | // copy and expand the message block | ||
35 | for( t = 0; t < 16; t++ ) W[t] = (bytes[t*4] << 24) | ||
36 | +(bytes[t*4 + 1] << 16) | ||
37 | +(bytes[t*4 + 2] << 8) | ||
38 | + bytes[t*4 + 3]; | ||
39 | for(; t< 80; t++ ) W[t] = lrot( W[t-3]^W[t-8]^W[t-14]^W[t-16], 1 ); | ||
40 | |||
41 | /* main loop */ | ||
42 | uint32_t temp; | ||
43 | for( t = 0; t < 80; t++ ) | ||
44 | { | ||
45 | if( t < 20 ) { | ||
46 | K = 0x5a827999; | ||
47 | f = (b & c) | ((~b) & d); | ||
48 | } else if( t < 40 ) { | ||
49 | K = 0x6ed9eba1; | ||
50 | f = b ^ c ^ d; | ||
51 | } else if( t < 60 ) { | ||
52 | K = 0x8f1bbcdc; | ||
53 | f = (b & c) | (b & d) | (c & d); | ||
54 | } else { | ||
55 | K = 0xca62c1d6; | ||
56 | f = b ^ c ^ d; | ||
57 | } | ||
58 | temp = lrot(a,5) + f + e + W[t] + K; | ||
59 | e = d; | ||
60 | d = c; | ||
61 | c = lrot(b,30); | ||
62 | b = a; | ||
63 | a = temp; | ||
64 | //printf( "t=%d %08x %08x %08x %08x %08x\n",t,a,b,c,d,e ); | ||
65 | } | ||
66 | |||
67 | /* add variables */ | ||
68 | H0 += a; | ||
69 | H1 += b; | ||
70 | H2 += c; | ||
71 | H3 += d; | ||
72 | H4 += e; | ||
73 | |||
74 | //printf( "Current: %08x %08x %08x %08x %08x\n",H0,H1,H2,H3,H4 ); | ||
75 | /* all bytes have been processed */ | ||
76 | unprocessedBytes = 0; | ||
77 | } | ||
78 | |||
79 | void Sha1::update( const char* data, int num ) | ||
80 | { | ||
81 | // add these bytes to the running total | ||
82 | size += num; | ||
83 | |||
84 | // repeat until all data is processed | ||
85 | while( num > 0 ) | ||
86 | { | ||
87 | // number of bytes required to complete block | ||
88 | int needed = 64 - unprocessedBytes; | ||
89 | |||
90 | // number of bytes to copy (use smaller of two) | ||
91 | int toCopy = (num < needed) ? num : needed; | ||
92 | |||
93 | // Copy the bytes | ||
94 | memcpy( bytes + unprocessedBytes, data, toCopy ); | ||
95 | |||
96 | // Bytes have been copied | ||
97 | num -= toCopy; | ||
98 | data += toCopy; | ||
99 | unprocessedBytes += toCopy; | ||
100 | |||
101 | // there is a full block | ||
102 | if( unprocessedBytes == 64 ) process(); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | unsigned char* Sha1::getDigest() | ||
107 | { | ||
108 | // save the message size | ||
109 | uint32_t totalBitsL = size << 3; | ||
110 | uint32_t totalBitsH = size >> 29; | ||
111 | |||
112 | // add 0x80 to the message | ||
113 | update( "\x80", 1 ); | ||
114 | |||
115 | unsigned char footer[64] = { | ||
116 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
117 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
118 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
119 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
120 | |||
121 | // block has no room for 8-byte filesize, so finish it | ||
122 | if( unprocessedBytes > 56 ) | ||
123 | update( (char*)footer, 64 - unprocessedBytes); | ||
124 | |||
125 | // how many zeros do we need | ||
126 | int neededZeros = 56 - unprocessedBytes; | ||
127 | |||
128 | // store file size (in bits) in big-endian format | ||
129 | toBigEndian( totalBitsH, footer + neededZeros ); | ||
130 | toBigEndian( totalBitsL, footer + neededZeros + 4 ); | ||
131 | |||
132 | // finish the final block | ||
133 | update( (char*)footer, neededZeros + 8 ); | ||
134 | |||
135 | // allocate memory for the digest bytes | ||
136 | unsigned char* digest = new unsigned char[20]; | ||
137 | |||
138 | // copy the digest bytes | ||
139 | toBigEndian( H0, digest ); | ||
140 | toBigEndian( H1, digest + 4 ); | ||
141 | toBigEndian( H2, digest + 8 ); | ||
142 | toBigEndian( H3, digest + 12 ); | ||
143 | toBigEndian( H4, digest + 16 ); | ||
144 | |||
145 | // return the digest | ||
146 | return digest; | ||
147 | } | ||
148 | |||
149 | uint32_t Sha1::lrot( uint32_t x, int bits ) | ||
150 | { | ||
151 | return (x<<bits) | (x>>(32 - bits)); | ||
152 | }; | ||
153 | |||
154 | void Sha1::toBigEndian( uint32_t num, unsigned char* byte ) | ||
155 | { | ||
156 | byte[0] = (unsigned char)(num>>24); | ||
157 | byte[1] = (unsigned char)(num>>16); | ||
158 | byte[2] = (unsigned char)(num>>8); | ||
159 | byte[3] = (unsigned char)num; | ||
160 | } | ||
161 | |||
diff --git a/src/sha1.h b/src/sha1.h new file mode 100644 index 0000000..ab6081d --- /dev/null +++ b/src/sha1.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* sha1.h | ||
2 | |||
3 | Copyright (c) 2005 Michael D. Leonhard | ||
4 | |||
5 | http://tamale.net/ | ||
6 | |||
7 | This file is licensed under the terms described in the | ||
8 | accompanying LICENSE file. | ||
9 | */ | ||
10 | |||
11 | #ifndef SHA1_H | ||
12 | #define SHA1_H | ||
13 | |||
14 | #include <stdint.h> | ||
15 | |||
16 | /** | ||
17 | * Calculates SHA-1 sums. This is based strongly on code from Michael D. | ||
18 | * Leonhard who released his code under the terms of the MIT license, thank you! | ||
19 | */ | ||
20 | class Sha1 | ||
21 | { | ||
22 | public: | ||
23 | Sha1(); | ||
24 | ~Sha1(); | ||
25 | |||
26 | void update( const char* data, int num ); | ||
27 | unsigned char* getDigest(); | ||
28 | |||
29 | // utility methods | ||
30 | static uint32_t lrot( uint32_t x, int bits ); | ||
31 | static void toBigEndian( uint32_t in, unsigned char* out ); | ||
32 | |||
33 | private: | ||
34 | // fields | ||
35 | uint32_t H0, H1, H2, H3, H4; | ||
36 | unsigned char bytes[64]; | ||
37 | int unprocessedBytes; | ||
38 | uint32_t size; | ||
39 | void process(); | ||
40 | }; | ||
41 | |||
42 | #endif | ||
diff --git a/src/tests/md5.cpp b/src/tests/md5.cpp new file mode 100644 index 0000000..dea957b --- /dev/null +++ b/src/tests/md5.cpp | |||
@@ -0,0 +1,27 @@ | |||
1 | #include "bu/sio.h" | ||
2 | #include "bu/file.h" | ||
3 | #include "bu/md5.h" | ||
4 | |||
5 | using Bu::sio; | ||
6 | |||
7 | int main( int argc, char *argv[] ) | ||
8 | { | ||
9 | argv++, argc--; | ||
10 | for(; *argv; argv++ ) | ||
11 | { | ||
12 | Bu::File fIn( *argv, Bu::File::Read ); | ||
13 | Bu::Md5 m; | ||
14 | |||
15 | char buf[1000]; | ||
16 | for(;;) | ||
17 | { | ||
18 | int iRead = fIn.read( buf, 1000 ); | ||
19 | m.addData( buf, iRead ); | ||
20 | if( iRead < 1000 ) | ||
21 | break; | ||
22 | } | ||
23 | |||
24 | sio << m.getResult() << " *" << *argv << sio.nl; | ||
25 | } | ||
26 | } | ||
27 | |||
diff --git a/src/tests/stdstream.cpp b/src/tests/stdstream.cpp index cb22e22..0949a8c 100644 --- a/src/tests/stdstream.cpp +++ b/src/tests/stdstream.cpp | |||
@@ -24,8 +24,8 @@ int main() | |||
24 | sio << 0.123 << sio.nl; | 24 | sio << 0.123 << sio.nl; |
25 | sio << true << " and then " << false << sio.nl; | 25 | sio << true << " and then " << false << sio.nl; |
26 | 26 | ||
27 | //for( int j = 2; j <= 36; j++ ) | 27 | for( int j = 2; j <= 36; j++ ) |
28 | // sio << "radix(" << j << ") = " << Fmt().radix( j ) << 255 << sio.nl; | 28 | sio << "radix(" << j << ") = " << Fmt().radix( j ).width( 8 ).align( Fmt::Right ) << 255 << sio.nl; |
29 | 29 | ||
30 | return 0; | 30 | return 0; |
31 | } | 31 | } |