-
Notifications
You must be signed in to change notification settings - Fork 0
/
CRC.java
107 lines (97 loc) · 4.92 KB
/
CRC.java
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
package crc;
public class CRC {
public static void main(String[] args) {
calc(encode(14390039), 0x589);
}
private static int encode(int NZK) {
//îáíóëÿåì ñîîáùåíèå
int message = 0;
//ïåðåâåä¸ííûé â äâîè÷íóþ ñèñòåìó íîìåð çà÷¸òíîé êíèæêè,
//ãäå öèôðà - çàêîäèðîâàíà 4ìÿ áèòàìè
// 1 4 3 9 0 0 3 9
//0001 0100 0011 1001 0000 0000 0011 1001
System.out.println("=======================================");
System.out.println("¹\tdec\tbin\tshift<<");
System.out.println(".......................................");
//Öèêë, íà÷èíàÿ ñ 7ìè è çàêàí÷èâàÿ íóë¸ì
for (int i = 7; i >= 0; i--) {
//Ìû áåð¸ì íîìåð çà÷¸òêè è äåëèì íà äåñÿòü â ñòåïåíè i, à çàòåì áåð¸ì îñòàòîê îò äåëåíèÿ íà 10
//Ïðèìåð: (891 / 100) % 10 = 8; (891 / 10) % 10 = 9; (891) % 10 = 1
int decimal = (NZK / (int) Math.pow(10, i)) % 10;
//Çàòåì ìû äîëæíû ñäâèíóòü ýòî ÷èñëî âëåâî íà îïðåäåë¸ííîé êîë-âî ïîçèöèé, âñåãäà êðàòíîå 4ì
//Ïðèáàâëÿåì ê ðåçóëüòàòó ÷èñëî ñî ñäâèãîì
message += decimal << i * 4;
//Ïåðåâîäèì â áèíàðíóþ ñòðîêó, ïî 4 ñèìâîëà
System.out.println(7 - i + "\t" + decimal + "\t" + toBinary(decimal, 4) + "\t" + i * 4);
}
System.out.println("=======================================");
System.out.println("ÍÇÊ â áèíàðíîì ïðåäñòàâëåíèè:");
System.out.println(".......................................");
System.out.println(toBinary(message, 32));
return message;
}
private static void calc(int M, int G) {
//çàíîñèì â CRC íîëü
int result = 0;
//íàøà êîìáèíàöèÿ:
//0001 0100 0011 1001 0000 0000 0011 1001
//íà÷èíàÿ ñ ïåðâîãî ïðîâåðÿåì áèòû ñäâèãàÿñü ñîîáùåíèå âëåâî íà îäíó ïîçèöèþ
//400 èòåðàöèé, òàê êàê äëèíà ñîîáùåíèÿ - 400
for (int i = 399; i >= 0; i--) {
//÷òîáû âçÿòü áèò èç ïîñëåäîâàòåëüíîñòè, ñäâèãàåì å¸ âïðàâî íà òàêîå êîëè÷åñòâî ïîçèöèé,
//÷òîáû ïîñëåäíèì â êîìáèíàöèè îêàçàëñÿ íóæíûé íàì è äåëèì ñ îñòàòêîì íà 2, ÷òîáû âçÿòü åãî çíà÷åíèå
//(i + 16) % 32 êîëåáëåòñÿ îò 0 äî 31, ïðè ýòîì â ïåðâîé èòåðàöèè, êîãäà çíà÷åíèå i=399 ìû äîëæíû ïîëó÷èòü 31
//(399 + 16) % 32 = 31
//[0]001 0100 0011 1001 0000 0000 0011 1001 >> 31 =
//[0] (ïðè ýòîì ïðàâûå 31 áèò îòáðîñèëèñü)
//[0] & 0x1 = 0 (òàêèì ñïîñîáîì áåð¸ì è âñå îñòàâøèåñÿ áèòû)
result = iterate(399 - i, result, (M >> (i + 16) % 32) & 0x1, G);
}
//Êîíåö öåïî÷êè - ðàíåå ðàññ÷èòàííûé CRC (53CA) èëè öåïî÷êà íóëåé
int chainEnd = 0x53CA;
//ïðîäîëæèò ðàñ÷¸ò ñ 16þ (ïî ñòåïåíè ïîëèíîìà) áèòàìè êîíöà
for (int i = 15; i >= 0; i--) {
//áèòû äëÿ ïðîäîëæåíèÿ ðàñ÷¸òà áóäåì áðàòü ëèáî èç öåïî÷êè íóëåé, ÷òîáû âû÷èñëèòü CRC
//ëèáî èç âû÷èñëåííîãî ðàíåå CRC, ÷òîáû âûïîëíèòü ïðîâåðêó
result = iterate(400 + (15 - i), result, (chainEnd >> i) & 0x1, G);
}
System.out.println("=======================================");
}
private static int iterate(int number, int currentBits, int inBit, int G) {
//ñìîòðèì êàêîé áèò íà äàííûé ìîìåíò ïåðâûé (âûäâèíóòûé) â ðåãèñòðå ïóò¸ì ñäâèãà, à çíà÷èò è îòáðàñûâàíèÿ çíà÷åíèé ìëàäøèõ 15 áèò
int outBit = currentBits >> 15;
//ñäâèãàåì âëåâî íà îäíó ïîçèöóþ, âûäâèãàåì ñòàðøèé áèò, îñâîáîæäàåì ìëàäøèé
currentBits <<= 1;
//îáðåçàåì çíà÷åíèå äî íóæíûõ íàì 16òè áèò
currentBits %= (int) Math.pow(2, 16);
//äîáàâëÿåì â êîíåö ðåãèñòðà, íà îñâîáîäèâøååñÿ ìåñòî ñëåäóùèé áèò èç êîìáèíàöèè
currentBits += inBit;
//åñëè âûäâèíóòûé áèò åäèíèöà
if (outBit == 1) {
//âûïîëíÿåì XOR
currentBits ^= G;
}
System.out.println("=======================================");
System.out.println("¹:\t" + number);
System.out.println("---------------------------------------");
System.out.println("out:\t" + outBit);
System.out.println("in:\t" + inBit);
System.out.println("---------------------------------------");
System.out.println("\tBin\t\t\tHex");
System.out.println(".......................................");
System.out.println("CRC:\t" + toBinary(currentBits, 16) + "\t" + toHex(currentBits, 4));
return currentBits;
}
private static String toBinary(int data, int len) {
return formatTo4(formatToLen(Integer.toBinaryString(data), len));
}
private static String toHex(int data, int len) {
return "0x" + formatToLen(Integer.toHexString(data), len).toUpperCase();
}
private static String formatTo4(String string) {
return string.replaceAll("(.{4})", "$1 ");
}
private static String formatToLen(String string, int length) {
return String.format("%" + length + "s", string).replace(' ', '0');
}
}