1 /*****************************************************************************\
3 * Name : checksums group *
4 * Authors: Chris Koeritz *
6 *******************************************************************************
7 * Copyright (c) 1992-$now By Author. This program is free software; you can *
8 * redistribute it and/or modify it under the terms of the GNU General Public *
9 * License as published by the Free Software Foundation; either version 2 of *
10 * the License or (at your option) any later version. This is online at: *
11 * http://www.fsf.org/copyleft/gpl.html *
12 * Please send any updates to: fred@gruntose.com *
13 \*****************************************************************************/
15 #include "checksums.h"
17 #include <basis/definitions.h>
19 using namespace basis;
21 namespace structures {
23 const int HIGHEST_MOD_VALUE = 32014;
25 unsigned int checksums::bizarre_checksum(const abyte *data, int length)
28 for (int i = 0; i < length; i++) sum += data[i] % 23 + i % 9;
29 sum = (sum % (HIGHEST_MOD_VALUE - 1)) + 1;
30 return (unsigned int)sum;
33 // fletcher checksum is from Dr. Dobbs Journal May 1992, pp. 32-38.
35 basis::un_short checksums::fletcher_checksum(const abyte *data, int length)
38 basis::un_int sum2 = 0;
39 const abyte *buffer = data;
42 sum1 += int(*buffer++);
43 // check for overflow into high byte.
44 if (sum1 > 255) sum1++;
45 sum1 &= 0xFF; // remove any bits in high byte for next sum.
46 sum2 += basis::un_int(sum1);
48 if (sum1 == 255) sum1 = 0;
49 unsigned int fletch = basis::un_int(sum2 & 0xFF);
51 fletch |= basis::un_int(sum1 & 0xFF);
53 return basis::un_short(fletch);
56 basis::un_short checksums::rolling_fletcher_checksum(basis::un_short previous, const abyte *data,
58 { return previous ^ fletcher_checksum(data, len); }
60 abyte checksums::byte_checksum(const abyte *data, int length)
63 for (int i = 0; i < length; i++) to_return += abyte(data[i]);
67 basis::un_int checksums::short_checksum(const abyte *data, int length)
69 basis::un_int to_return = 0;
70 for (int i = 0; i < length; i++) to_return += data[i];
74 basis::un_int checksums::hash_bytes(const void *key_data, int key_length)
76 if (!key_data) return 0; // error!
77 if (!key_length) return 0; // ditto!
79 abyte *our_key = (abyte *)key_data;
80 abyte hashed[4] = { 0, 0, 0, 0 };
83 for (int i = 0; i < key_length; i++) {
84 // add to the primary area.
85 hashed[fill_posn] = hashed[fill_posn] + our_key[i];
87 if (fill_posn >= 4) fill_posn = 0;
88 // add to the secondary area (the next in rotation after primary).
89 hashed[fill_posn] = hashed[fill_posn] + (our_key[i] / 4);
92 basis::un_int to_return = 0;
93 for (int j = 0; j < 4; j++) to_return = (to_return << 8) + hashed[j];