1 /* cksum -- calculate and print POSIX.2 checksums and sizes of files
2 Copyright (C) 1992 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* Written by Q. Frank Xia, qx@math.columbia.edu.
19 Cosmetic changes and reorganization by David MacKenzie, djm@gnu.ai.mit.edu.
21 Usage: cksum [file...]
23 The code segment between "#ifdef CRCTAB" and "#else" is the code
24 which calculates the "crctab". It is included for those who want
25 verify the correctness of the "crctab". To recreate the "crctab",
28 cc -DCRCTAB -o crctab cksum.c
31 As Bruce Evans pointed out to me, the crctab in the sample C code
32 in 4.9.10 Rationale of P1003.2/D11.2 is represented in reversed order.
33 Namely, 0x01 is represented as 0x80, 0x02 is represented as 0x40, etc.
34 The generating polynomial is crctab[0x80]=0xedb88320 instead of
35 crctab[1]=0x04C11DB7. But the code works only for a non-reverse order
36 crctab. Therefore, the sample implementation is wrong.
38 This software is compatible with neither the System V nor the BSD
39 `sum' program. It is supposed to conform to P1003.2/D11.2,
40 except foreign language interface (4.9.5.3 of P1003.2/D11.2) support.
41 Any inconsistency with the standard except 4.9.5.3 is a bug. */
47 #define BIT(x) ( (unsigned long)1 << (x) )
50 /* The generating polynomial is
52 32 26 23 22 16 12 11 10 8 7 5 4 2 1
53 G(X)=X + X + X + X + X + X + X + X + X + X + X + X + X + X + 1
55 The i bit in GEN is set if X^i is a summand of G(X) except X^32. */
57 #define GEN (BIT(26)|BIT(23)|BIT(22)|BIT(16)|BIT(12)|BIT(11)|BIT(10)\
58 |BIT(8) |BIT(7) |BIT(5) |BIT(4) |BIT(2) |BIT(1) |BIT(0));
68 for (i = 1; i < 8; i++)
69 r[i] = (r[i - 1] & SBIT) ? (r[i - 1] << 1) ^ r[0] : r[i - 1] << 1;
76 unsigned long rem = 0;
79 for (i = 0; i < 8; i++)
83 return rem & 0xFFFFFFFF; /* Make it run on 64-bit machine. */
92 printf ("unsigned long crctab[256] = {\n 0x0");
93 for (i = 0; i < 51; i++)
95 printf (",\n 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X",
96 remainder (i * 5 + 1), remainder (i * 5 + 2), remainder (i * 5 + 3),
97 remainder (i * 5 + 4), remainder (i * 5 + 5));
106 #include <sys/types.h>
109 /* Number of bytes to read at once. */
110 #define BUFLEN (1 << 16)
112 unsigned long crctab[256] =
115 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B,
116 0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6,
117 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
118 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC,
119 0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, 0x6ED82B7F,
120 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A,
121 0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
122 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58,
123 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033,
124 0xA4AD16EA, 0xA06C0B5D, 0xD4326D90, 0xD0F37027, 0xDDB056FE,
125 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
126 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4,
127 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, 0x34867077, 0x30476DC0,
128 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5,
129 0x2AC12072, 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
130 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, 0x7897AB07,
131 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C,
132 0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1,
133 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
134 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B,
135 0xBB60ADFC, 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698,
136 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D,
137 0x94EA7B2A, 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
138 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, 0xC6BCF05F,
139 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34,
140 0xDC3ABDED, 0xD8FBA05A, 0x690CE0EE, 0x6DCDFD59, 0x608EDB80,
141 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB,
142 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A,
143 0x58C1663D, 0x558240E4, 0x51435D53, 0x251D3B9E, 0x21DC2629,
144 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C,
145 0x3B5A6B9B, 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF,
146 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, 0xF12F560E,
147 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65,
148 0xEBA91BBC, 0xEF68060B, 0xD727BBB6, 0xD3E6A601, 0xDEA580D8,
149 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
150 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2,
151 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, 0x9B3660C6, 0x9FF77D71,
152 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74,
153 0x857130C3, 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640,
154 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, 0x7B827D21,
155 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A,
156 0x61043093, 0x65C52D24, 0x119B4BE9, 0x155A565E, 0x18197087,
157 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
158 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D,
159 0x2056CD3A, 0x2D15EBE3, 0x29D4F654, 0xC5A92679, 0xC1683BCE,
160 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB,
161 0xDBEE767C, 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18,
162 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, 0x89B8FD09,
163 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662,
164 0x933EB0BB, 0x97FFAD0C, 0xAFB010B1, 0xAB710D06, 0xA6322BDF,
165 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4
168 /* The name this program was run with. */
171 /* Nonzero if any of the files read were the standard input. */
174 /* Calculate and print the checksum and length in bytes
175 of file FILE, or of the standard input if FILE is "-".
176 If PRINT_NAME is nonzero, print FILE next to the checksum and size.
177 Return 0 if successful, -1 if an error occurs. */
180 cksum (file, print_name)
184 unsigned char buf[BUFLEN];
185 unsigned long crc = 0;
190 if (!strcmp (file, "-"))
197 fp = fopen (file, "r");
200 error (0, errno, "%s", file);
205 while ((bytes_read = fread (buf, 1, BUFLEN, fp)) > 0)
207 unsigned char *cp = buf;
209 length += bytes_read;
211 crc = (crc << 8) ^ crctab[((crc >> 24) ^ *(cp++)) & 0xFF];
216 error (0, errno, "%s", file);
217 if (strcmp (file, "-"))
222 if (strcmp (file, "-") && fclose (fp) == EOF)
224 error (0, errno, "%s", file);
229 while (bytes_read > 0)
231 crc = (crc << 8) ^ crctab[((crc >> 24) ^ bytes_read) & 0xFF];
235 crc = ~crc & 0xFFFFFFFF;
237 printf ("%10lu %8ld", crc, length);
239 printf (" %s", file);
252 program_name = argv[0];
257 if (cksum ("-", 0) < 0)
264 for (optind = 1; optind < argc; ++optind)
265 if (cksum (argv[optind], 1) < 0)
269 if (have_read_stdin && fclose (stdin) == EOF)
270 error (1, errno, "-");