-
Notifications
You must be signed in to change notification settings - Fork 0
/
api_checksum.c
82 lines (60 loc) · 1.88 KB
/
api_checksum.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include "api_checksum.h"
#define M 0x10000
unsigned int checksum(unsigned int low, unsigned int high) {
return low + (high * M);
}
unsigned int lower(char *a_string, int size) {
unsigned int lower = 0;
for (int i = 0 ; i < size ; i++) {
lower += a_string[i];
}
lower = lower % M;
return lower;
}
unsigned int higher(char *a_string, int size) {
unsigned int higher = 0;
for (int i = 0 ; i < size ; i++) {
higher += (size - i) * a_string[i];
}
higher = higher % M;
return higher;
}
int checksum_rolling_init(checksum_t *self, checksum_t *rolling_checksum,\
char *a_string) {
checksum_init(rolling_checksum, a_string, self->size);
unsigned int new_low = \
(self->low - self->a_string[0] + a_string[self->size -1])\
% M;
unsigned int new_high = \
(self->high - self->size * self->a_string[0] + new_low)\
% M;
rolling_checksum->low = new_low;
rolling_checksum->high = new_high;
rolling_checksum->checksum_applied_to_string = checksum(new_low, new_high);
return 0;
}
int checksum_calculate_checksum(checksum_t *self) {
self->low = lower(self->a_string, self->size);
self->high = higher(self->a_string, self->size);
self->checksum_applied_to_string = checksum(self->low, self->high);
return 0;
}
int checksum_init(checksum_t *self, char *a_string, int size) {
self->a_string = a_string;
self->size = size;
return 0;
}
int checksum_init_with_checksum_applied_to_string\
(checksum_t *self, char *a_string, int size) {
checksum_init(self, a_string, size);
checksum_calculate_checksum(self);
return 0;
}
int checksum_copy_from_checksum(checksum_t *self, checksum_t *other_checksum) {
self->a_string = other_checksum->a_string;
self->checksum_applied_to_string = other_checksum->checksum_applied_to_string;
self->size = other_checksum->size;
self->high = other_checksum->high;
self->low = other_checksum->low;
return 0;
}