source: trunk/gsdl/src/hashfile/hashfile.cpp@ 4

Last change on this file since 4 was 4, checked in by sjboddie, 25 years ago

Initial revision

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 3.9 KB
Line 
1#include <stdio.h>
2
3#define MAXNUMLEN 100 // bytes
4
5
6// The number class is used to store very long unsigned integers.
7// The least significant of each number is stored first. Numbers can
8// be no longer than MAXNUMLEN bytes long. A number with length=0
9// is considered to be equal to 0. There should be no extra zeros
10// at the front of the number.
11
12struct number {
13 unsigned int len;
14 unsigned char num[MAXNUMLEN];
15
16 number () {len = 0;}
17};
18
19
20// evaluates a = a + b
21// a and b can be the same number
22void my_inc (number &a, number &b) {
23 unsigned int carry = 0;
24 unsigned int num = 0;
25 unsigned int i = 0;
26
27 while ((carry || (i < a.len) || (i < b.len)) && (i < MAXNUMLEN)) {
28 num = carry;
29 if (i < a.len) num += a.num[i];
30 if (i < b.len) num += b.num[i];
31
32 if (num >= 256) {
33 num -= 256; // assumes that each number in the list < 256
34 carry = 1;
35 } else {
36 carry = 0;
37 }
38 a.num[i] = (unsigned char)num;
39
40 i++;
41 }
42
43 a.len = i;
44}
45
46
47// evaluates a = a - b if a >= b
48// returns true if the subtraction was possible
49int my_ifpos_dec (number &a, number &b) {
50 int carry = 0;
51 int num = 0;
52 unsigned int i = 0;
53 unsigned int len = 0; // the last non-zero digit
54
55 // make sure a >= b
56 if (b.len > a.len) return 0;
57 if (b.len == a.len) {
58 i = a.len - 1;
59 while (i >= 0) {
60 if (a.num[i] > b.num[i]) break;
61 if (a.num[i] < b.num[i]) return 0;
62 i--;
63 }
64 }
65
66 i = 0;
67 len = 0;
68 while ((i < a.len) || (i < b.len)) {
69 num = -carry;
70 if (i < a.len) num += a.num[i];
71 if (i < b.len) num -= b.num[i];
72
73 if (num < 0) {
74 num += 256; // assumes each number in the list < 256
75 carry = 1;
76 } else {
77 carry = 0;
78 }
79
80 a.num[i] = (unsigned char) num;
81
82 i++;
83 if (num != 0) len = i;
84 }
85
86 a.len = len;
87
88 if (carry) {
89 // panic, this should NOT happen
90 fprintf (stderr, "panic: error in my_ifpos_dec\n");
91 }
92
93 return 1;
94}
95
96
97char *my_convert_num (number &a) {
98 char *result = new char[a.len+2];
99 int i,len;
100 char convert[16] = {'0','1','2','3','4','5','6','7',
101 '8','9','a','b','c','d','e','f'};
102
103 // zero might be a special case
104 if (a.len == 0) {
105 result[0] = '0';
106 result[1] = '\0';
107 return result;
108 }
109
110 for (i=a.len-1, len=0; i >= 0; i--) {
111 result[len++] = convert[a.num[i]/16];
112 result[len++] = convert[a.num[i]%16];
113 }
114 result[len] = '\0';
115
116 return result;
117}
118
119
120char *hashfile (char *filename) {
121 FILE *infile = NULL;
122 int i;
123
124 // calculate the 8 multiples of the prime number to use
125 // in the long division
126 number primepow[8];
127 number pow;
128 number remainder;
129 unsigned char c;
130
131 // our prime number (618970019642690137449562111)
132 pow.num[0] = 255; pow.num[1] = 255;
133 pow.num[2] = 255; pow.num[3] = 255;
134 pow.num[4] = 255; pow.num[5] = 255;
135 pow.num[6] = 255; pow.num[7] = 255;
136 pow.num[8] = 255; pow.num[9] = 255;
137 pow.num[10] = 255; pow.num[11] = 1;
138 pow.len = 12;
139
140 for (i=0; i<8; i++) {
141 primepow[i] = pow;
142 my_inc (pow, pow);
143 }
144
145 infile = fopen (filename, "rb");
146 if (infile == NULL) {
147 return NULL;
148 }
149
150 remainder.len = 0;
151 c = (unsigned char)fgetc(infile);
152 while (!feof (infile)) {
153 // remainder = remainder * 256 + c
154 if (remainder.len == MAXNUMLEN-1) {
155 fprintf (stderr, "ERROR - number overflow\n");
156 return NULL;
157 }
158 for (i=remainder.len; i>0; i--) {
159 remainder.num[i] = remainder.num[i-1];
160 }
161 remainder.num[0] = c;
162 remainder.len = remainder.len+1;
163
164 for (i=7; i>=0; i--) {
165 my_ifpos_dec (remainder, primepow[i]);
166 }
167
168 c = (unsigned char)fgetc(infile);
169 }
170
171 fclose (infile);
172
173 return my_convert_num (remainder);
174}
175
176
177int main (int argc, char *argv[]) {
178 int i;
179 char *result;
180
181 for (i = 1; i < argc; i++) {
182 result = hashfile (argv[i]);
183 if (result == NULL) {
184 printf ("ERROR - could not process %s\n", argv[i]);
185 } else {
186 printf ("%s: %s\n", argv[i], result);
187 delete [] result;
188 }
189 }
190
191 return 0;
192}
Note: See TracBrowser for help on using the repository browser.