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
|
public class UserSolution { private static final int FRAMESIZE = 256 ; private static int num; private static int max; private static char [][] frames; private static int [] lookingTable; public void Init( int N, int [] size, char [] data, int M, Solution.Huffman[] code) { frames = new char [N][FRAMESIZE]; max = N; int len = 0 ; for ( int i = 0 ; i < M; i++) if (code[i].codewordLength > len) len = code[i].codewordLength; int mask = 0xFFFFFF >> ( 24 - len); //用于后面更新tmpCode lookingTable = new int [ 1 << len]; //查找表,存储tmpCode对应的code数组索引 for ( int i = 0 ; i < M; i++) for ( int j = 0 ; j < 1 << (len - code[i].codewordLength); j++) //长度为codewordLength的code,需要初始化2^(len-code[i].codewordLength)个位置 lookingTable[code[i].codeword << (len - code[i].codewordLength) | j] = i; int baseIdx = 0 ; for ( int i = 0 ; i < N/ 16 ; i++) { int bitIdx = 0 ; int frameCharIdx = 0 ; int codeLen = 0 ; int tmpCode = 0 ; while (frameCharIdx < 4096 ) { if (bitIdx == 32768 ) { //由于使用固定长度的tmpCode,因此需要处理最后bit的边界情况 tmpCode = tmpCode << (len - codeLen); codeLen = len; } while (codeLen < len) { //每次读入len位数据,判断其对应的code int diff = len - codeLen; if ( 8 - bitIdx% 8 >= diff) { //当前data剩余位数足够 tmpCode = tmpCode << diff | (data[baseIdx + (bitIdx>> 3 )] << (bitIdx% 8 ) >> ( 8 - diff)); //取对应位,更新tmpCode bitIdx += diff; codeLen = len; } else { //当前data剩余位数不够 int rest = 8 - bitIdx% 8 ; tmpCode = tmpCode << rest | (data[baseIdx + (bitIdx>> 3 )] & 0xFF >> (bitIdx% 8 )); //取对应位,更新tmpCode bitIdx += rest; codeLen += rest; } } //此时tmpCode必然对应一个明文,更新到frames中 frames[(i<< 4 ) + frameCharIdx/FRAMESIZE][frameCharIdx%FRAMESIZE] = ( char )code[lookingTable[tmpCode]].symbol; frameCharIdx++; codeLen -= code[lookingTable[tmpCode]].codewordLength; //减去上一个char对应的有效位数 tmpCode = tmpCode & (mask >> code[lookingTable[tmpCode]].codewordLength); //去除上一个char对应的有效位后,剩余的tmpCode } baseIdx += size[i]; } //从D frames反推O frames,注意每16个frame为一个block for ( int i = 0 ; i < N/ 16 ; i++) for ( int k = 1 ; k < 16 ; k++) for ( int j = 0 ; j < FRAMESIZE; j++) frames[(i<< 4 ) + k][j] = ( char )(frames[(i<< 4 ) + k][j] + frames[(i<< 4 ) + k - 1 ][j] - 128 ); } public void Goto( int frame) { num = frame; } public int Tick( char [] screen) { if (num < max) num++; for ( int i = 0 ; i < FRAMESIZE; i++) screen[i] = frames[num - 1 ][i]; return num - 1 ; } } |