-
Notifications
You must be signed in to change notification settings - Fork 4
/
crc.ml
169 lines (145 loc) · 7.27 KB
/
crc.ml
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
(*******************************************************************************
This file is a part of mp3packer.
mp3packer is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
mp3packer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with mp3packer; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*******************************************************************************)
let lame_lookup = [| (* Stolen directly out of the LAME VbrTag.c file (I don't know how to do CRCs! Why am I doing this?!) *)
0x0000; 0xC0C1; 0xC181; 0x0140; 0xC301; 0x03C0; 0x0280; 0xC241;
0xC601; 0x06C0; 0x0780; 0xC741; 0x0500; 0xC5C1; 0xC481; 0x0440;
0xCC01; 0x0CC0; 0x0D80; 0xCD41; 0x0F00; 0xCFC1; 0xCE81; 0x0E40;
0x0A00; 0xCAC1; 0xCB81; 0x0B40; 0xC901; 0x09C0; 0x0880; 0xC841;
0xD801; 0x18C0; 0x1980; 0xD941; 0x1B00; 0xDBC1; 0xDA81; 0x1A40;
0x1E00; 0xDEC1; 0xDF81; 0x1F40; 0xDD01; 0x1DC0; 0x1C80; 0xDC41;
0x1400; 0xD4C1; 0xD581; 0x1540; 0xD701; 0x17C0; 0x1680; 0xD641;
0xD201; 0x12C0; 0x1380; 0xD341; 0x1100; 0xD1C1; 0xD081; 0x1040;
0xF001; 0x30C0; 0x3180; 0xF141; 0x3300; 0xF3C1; 0xF281; 0x3240;
0x3600; 0xF6C1; 0xF781; 0x3740; 0xF501; 0x35C0; 0x3480; 0xF441;
0x3C00; 0xFCC1; 0xFD81; 0x3D40; 0xFF01; 0x3FC0; 0x3E80; 0xFE41;
0xFA01; 0x3AC0; 0x3B80; 0xFB41; 0x3900; 0xF9C1; 0xF881; 0x3840;
0x2800; 0xE8C1; 0xE981; 0x2940; 0xEB01; 0x2BC0; 0x2A80; 0xEA41;
0xEE01; 0x2EC0; 0x2F80; 0xEF41; 0x2D00; 0xEDC1; 0xEC81; 0x2C40;
0xE401; 0x24C0; 0x2580; 0xE541; 0x2700; 0xE7C1; 0xE681; 0x2640;
0x2200; 0xE2C1; 0xE381; 0x2340; 0xE101; 0x21C0; 0x2080; 0xE041;
0xA001; 0x60C0; 0x6180; 0xA141; 0x6300; 0xA3C1; 0xA281; 0x6240;
0x6600; 0xA6C1; 0xA781; 0x6740; 0xA501; 0x65C0; 0x6480; 0xA441;
0x6C00; 0xACC1; 0xAD81; 0x6D40; 0xAF01; 0x6FC0; 0x6E80; 0xAE41;
0xAA01; 0x6AC0; 0x6B80; 0xAB41; 0x6900; 0xA9C1; 0xA881; 0x6840;
0x7800; 0xB8C1; 0xB981; 0x7940; 0xBB01; 0x7BC0; 0x7A80; 0xBA41;
0xBE01; 0x7EC0; 0x7F80; 0xBF41; 0x7D00; 0xBDC1; 0xBC81; 0x7C40;
0xB401; 0x74C0; 0x7580; 0xB541; 0x7700; 0xB7C1; 0xB681; 0x7640;
0x7200; 0xB2C1; 0xB381; 0x7340; 0xB101; 0x71C0; 0x7080; 0xB041;
0x5000; 0x90C1; 0x9181; 0x5140; 0x9301; 0x53C0; 0x5280; 0x9241;
0x9601; 0x56C0; 0x5780; 0x9741; 0x5500; 0x95C1; 0x9481; 0x5440;
0x9C01; 0x5CC0; 0x5D80; 0x9D41; 0x5F00; 0x9FC1; 0x9E81; 0x5E40;
0x5A00; 0x9AC1; 0x9B81; 0x5B40; 0x9901; 0x59C0; 0x5880; 0x9841;
0x8801; 0x48C0; 0x4980; 0x8941; 0x4B00; 0x8BC1; 0x8A81; 0x4A40;
0x4E00; 0x8EC1; 0x8F81; 0x4F40; 0x8D01; 0x4DC0; 0x4C80; 0x8C41;
0x4400; 0x84C1; 0x8581; 0x4540; 0x8701; 0x47C0; 0x4680; 0x8641;
0x8201; 0x42C0; 0x4380; 0x8341; 0x4100; 0x81C1; 0x8081; 0x4040;
|];;
let lame_update_byte gnu crc =
let temp = crc lxor gnu in
(crc lsr 8) lxor lame_lookup.(temp land 0xFF)
;;
let lame_update_reference gnu crc_ref =
let temp = !crc_ref lxor gnu in
crc_ref := (!crc_ref lsr 8) lxor lame_lookup.(temp land 0xFF)
;;
let lame_create str initial =
let crc_ref = ref initial in (* 0 for the LAME header *)
for i = 0 to String.length str - 1 do
lame_update_reference (Char.code str.[i]) crc_ref
done;
!crc_ref
;;
let lame_create_subptr ptr off len initial =
let crc_ref = ref initial in (* 0 for the LAME header *)
for i = off to off + len - 1 do
lame_update_reference (Ptr.get_byte ptr i) crc_ref
done;
!crc_ref
;;
let lame_create_ptrref r initial =
let crc_ref = ref initial in
let iter_me _ () ptr off len =
crc_ref := lame_create_subptr ptr off len !crc_ref
in
Ptr.Ref.iter iter_me () r;
!crc_ref
;;
(* Apparently the MP3 CRC is set up different from the LAME one *)
(* The MP3 CRC uses the generator 0x18005 with an initial CRC of 0xFFFF and no ending XOR *)
(* LAME's actually seems to be the same, but the bits are reversed, and it starts with 0x0000 instead of 0xFFFF *)
let mp3_lookup = [|
0x0000; 0x8005; 0x800f; 0x000a; 0x801b; 0x001e; 0x0014; 0x8011;
0x8033; 0x0036; 0x003c; 0x8039; 0x0028; 0x802d; 0x8027; 0x0022;
0x8063; 0x0066; 0x006c; 0x8069; 0x0078; 0x807d; 0x8077; 0x0072;
0x0050; 0x8055; 0x805f; 0x005a; 0x804b; 0x004e; 0x0044; 0x8041;
0x80c3; 0x00c6; 0x00cc; 0x80c9; 0x00d8; 0x80dd; 0x80d7; 0x00d2;
0x00f0; 0x80f5; 0x80ff; 0x00fa; 0x80eb; 0x00ee; 0x00e4; 0x80e1;
0x00a0; 0x80a5; 0x80af; 0x00aa; 0x80bb; 0x00be; 0x00b4; 0x80b1;
0x8093; 0x0096; 0x009c; 0x8099; 0x0088; 0x808d; 0x8087; 0x0082;
0x8183; 0x0186; 0x018c; 0x8189; 0x0198; 0x819d; 0x8197; 0x0192;
0x01b0; 0x81b5; 0x81bf; 0x01ba; 0x81ab; 0x01ae; 0x01a4; 0x81a1;
0x01e0; 0x81e5; 0x81ef; 0x01ea; 0x81fb; 0x01fe; 0x01f4; 0x81f1;
0x81d3; 0x01d6; 0x01dc; 0x81d9; 0x01c8; 0x81cd; 0x81c7; 0x01c2;
0x0140; 0x8145; 0x814f; 0x014a; 0x815b; 0x015e; 0x0154; 0x8151;
0x8173; 0x0176; 0x017c; 0x8179; 0x0168; 0x816d; 0x8167; 0x0162;
0x8123; 0x0126; 0x012c; 0x8129; 0x0138; 0x813d; 0x8137; 0x0132;
0x0110; 0x8115; 0x811f; 0x011a; 0x810b; 0x010e; 0x0104; 0x8101;
0x8303; 0x0306; 0x030c; 0x8309; 0x0318; 0x831d; 0x8317; 0x0312;
0x0330; 0x8335; 0x833f; 0x033a; 0x832b; 0x032e; 0x0324; 0x8321;
0x0360; 0x8365; 0x836f; 0x036a; 0x837b; 0x037e; 0x0374; 0x8371;
0x8353; 0x0356; 0x035c; 0x8359; 0x0348; 0x834d; 0x8347; 0x0342;
0x03c0; 0x83c5; 0x83cf; 0x03ca; 0x83db; 0x03de; 0x03d4; 0x83d1;
0x83f3; 0x03f6; 0x03fc; 0x83f9; 0x03e8; 0x83ed; 0x83e7; 0x03e2;
0x83a3; 0x03a6; 0x03ac; 0x83a9; 0x03b8; 0x83bd; 0x83b7; 0x03b2;
0x0390; 0x8395; 0x839f; 0x039a; 0x838b; 0x038e; 0x0384; 0x8381;
0x0280; 0x8285; 0x828f; 0x028a; 0x829b; 0x029e; 0x0294; 0x8291;
0x82b3; 0x02b6; 0x02bc; 0x82b9; 0x02a8; 0x82ad; 0x82a7; 0x02a2;
0x82e3; 0x02e6; 0x02ec; 0x82e9; 0x02f8; 0x82fd; 0x82f7; 0x02f2;
0x02d0; 0x82d5; 0x82df; 0x02da; 0x82cb; 0x02ce; 0x02c4; 0x82c1;
0x8243; 0x0246; 0x024c; 0x8249; 0x0258; 0x825d; 0x8257; 0x0252;
0x0270; 0x8275; 0x827f; 0x027a; 0x826b; 0x026e; 0x0264; 0x8261;
0x0220; 0x8225; 0x822f; 0x022a; 0x823b; 0x023e; 0x0234; 0x8231;
0x8213; 0x0216; 0x021c; 0x8219; 0x0208; 0x820d; 0x8207; 0x0202;
|];;
let mp3_update_byte gnu crc =
(* let temp = crc lxor (gnu lsl 8) in*)
((crc lsl 8) land 0xFFFF) lxor mp3_lookup.(((crc lsr 8) lxor gnu) land 0xFF)
;;
let mp3_update_reference gnu crc_ref =
(* let temp = !crc_ref lxor (gnu lsl 8) in*)
crc_ref := ((!crc_ref lsl 8) land 0xFFFF) lxor mp3_lookup.((!crc_ref lsr 8) lxor gnu)
;;
let mp3_create str initial =
let crc_ref = ref initial in (* 0 for the LAME header *)
for i = 0 to String.length str - 1 do
mp3_update_reference (Char.code str.[i]) crc_ref
done;
!crc_ref
;;
let mp3_create_subptr ptr off len initial =
let crc_ref = ref initial in (* 0 for the LAME header *)
for i = off to off + len - 1 do
mp3_update_reference (Ptr.get_byte ptr i) crc_ref
done;
!crc_ref
;;
let mp3_create_ptrref r initial =
let crc_ref = ref initial in
let iter_me _ () ptr off len =
crc_ref := mp3_create_subptr ptr off len !crc_ref
in
Ptr.Ref.iter iter_me () r;
!crc_ref
;;