1 /***************************************************************************
2 * Copyright (C) 2007 by SukkoPera *
3 * sukkopera@sukkology.net *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "multihash.h"
24 #define READBUF_SIZE 8192
27 void multihash_init (multihash *mh) {
29 (mh -> crc32_s)[0] = '\0';
30 mh -> crc32 = 0xffffffff;
33 (mh -> md4_s)[0] = '\0';
34 md4_starts (&(mh -> md4));
37 (mh -> md5_s)[0] = '\0';
38 Md5Initialise (&(mh -> md5));
41 (mh -> ed2k_s)[0] = '\0';
42 ed2khash_starts (&(mh -> ed2k));
45 (mh -> sha1_s)[0] = '\0';
46 Sha1Initialise (&(mh -> sha1));
49 (mh -> sha2_s)[0] = '\0';
50 Sha256Initialise (&(mh -> sha2));
57 void multihash_update (multihash *mh, unsigned char *data, int bytes) {
59 mh -> crc32 = CrcUpdate (mh -> crc32, data, bytes);
62 md4_update (&(mh -> md4), data, bytes);
65 Md5Update (&(mh -> md5), data, bytes);
68 ed2khash_update (&(mh -> ed2k), data, bytes);
71 Sha1Update (&(mh -> sha1), data, bytes);
74 Sha256Update (&(mh -> sha2), data, bytes);
81 void multihash_finish (multihash *mh) {
82 unsigned char buf[MAX_DIGESTSIZE];
86 mh -> crc32 ^= 0xffffffff;
87 snprintf (mh -> crc32_s, LEN_CRC32 + 1, "%08x", mh -> crc32);
90 md4_finish (&(mh -> md4), buf);
91 for (bytes = 0; bytes < LEN_MD4 / 2; bytes++)
92 sprintf (mh -> md4_s + 2*bytes, "%02x", buf[bytes]);
93 (mh -> md4_s)[LEN_MD4] = '\0';
96 /* MD5_HASH struct that receives the finalised MD5 hash */
98 Md5Finalise (&(mh -> md5), &md5_hash);
99 /* copy the final MD5 hash as hex string to the multihash struct */
100 for (bytes = 0; bytes < LEN_MD5 / 2; bytes++)
101 sprintf (mh -> md5_s + 2*bytes, "%02x", md5_hash.bytes[bytes]);
102 (mh -> md5_s)[LEN_MD5] = '\0';
105 ed2khash_finish (&(mh -> ed2k), buf);
106 for (bytes = 0; bytes < LEN_ED2K / 2; bytes++)
107 sprintf (mh -> ed2k_s + 2*bytes, "%02x", buf[bytes]);
108 (mh -> ed2k_s)[LEN_ED2K] = '\0';
111 /* SHA1_HASH struct that receives the finalised sha1 hash */
113 Sha1Finalise (&(mh -> sha1), &sha1_hash);
114 /* copy the final sha1 hash as hex string to the multihash struct */
115 for (bytes = 0; bytes < LEN_SHA1 / 2; bytes++)
116 sprintf (mh -> sha1_s + 2*bytes, "%02x", sha1_hash.bytes[bytes]);
117 (mh -> sha1_s)[LEN_SHA1] = '\0';
120 /* SHA256_HASH struct that receives the finalised sha2-256 hash */
121 SHA256_HASH sha2_hash;
122 Sha256Finalise (&(mh -> sha2), &sha2_hash);
123 /* copy the final sha2 hash as hex string to the multihash struct */
124 for (bytes = 0; bytes < LEN_SHA2 / 2; bytes++)
125 sprintf (mh -> sha2_s + 2*bytes, "%02x", sha2_hash.bytes[bytes]);
126 (mh -> sha2_s)[LEN_SHA2] = '\0';
133 int multihash_file (multihash *mh, char *filename) {
136 unsigned char data[READBUF_SIZE];
139 if ((fp = fopen (filename, "r"))) {
140 while ((bytes = fread (data, 1, READBUF_SIZE, fp)) != 0)
141 multihash_update (mh, data, bytes);
142 multihash_finish (mh);
146 /* Cannot open file */