Calcul du CCITT norme CRC avec le polynôme x^16 + x^12 + x^5 + 1 en Java
J'ai besoin d'aide avec le calcul du CCITT norme CRC avec le polynôme x^16 + x^12 + x^5 + 1 (0x1081) en Java. J'ai essayé de nombreux exemples sur internet, mais chacun d'entre eux renvoie à d'autres valeurs que celles de l'exemple.
Par exemple pour ce tableau [0xFC] [05] [11] le résultat doit être [27] [56].
L'aide de ce code:
public static void main(String[] args) {
byte[] array = new byte[3];
array[0] = (byte) 0xFC;
array[1] = (byte) 0x05;
array[2] = (byte) 0x11;
// array[3] = (byte) 0x00;
// array[4] = (byte) 0x00;
System.out.println(Integer.toHexString(crc16(array)));
}
private static final int POLYNOMIAL = 0x1081;
private static final int PRESET_VALUE = 0xFFFF;
public static int crc16(byte[] data) {
int current_crc_value = PRESET_VALUE;
for (int i = 0; i < data.length; i++) {
current_crc_value ^= data[i] & 0xFF;
for (int j = 0; j < 8; j++) {
if ((current_crc_value & 1) != 0) {
current_crc_value = (current_crc_value >>> 1) ^ POLYNOMIAL;
} else {
current_crc_value = current_crc_value >>> 1;
}
}
}
current_crc_value = ~current_crc_value;
return current_crc_value & 0xFFFF;
}
- Je obtenir de résultat FA DE
pas [27] [56]
L'aide de ce code:
public static void main(String[] args) {
int crc = 0x0000;
int polynomial = 0x1081;
//byte[] testBytes = "123456789".getBytes("ASCII");
// byte[] array = args[0].getBytes();
byte[] array = new byte[3];
array[0] = (byte) 0xFC;
array[1] = (byte) 0x05;
array[2] = (byte) 0x11;
for (byte b : array) {
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7-i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit) crc ^= polynomial;
}
}
crc &= 0xffff;
System.out.println("CRC16-CCITT = " + Integer.toHexString(crc));
}
- Je obtenir ce CRC16-CCITT = 8dca
L'aide de ce code:
private final int polynomial = 0x1081;
private int[] table = new int[256];
public int ComputeChecksum(int[] bytes) {
int crc = 0xffff;
for (int i = 0; i < bytes.length; ++i) {
int index = (crc ^ bytes[i]) % 256;
crc = (crc >> 8) ^ table[index];
}
return crc;
}
public CRC162() {
int value;
int temp;
for (int i = 0; i < table.length; ++i) {
value = 0;
temp = i;
for (byte j = 0; j < 8; ++j) {
if (((value ^ temp) & 0x0001) != 0) {
value = (value >> 1) ^ polynomial;
} else {
value >>= 1;
}
temp >>= 1;
}
table[i] = value;
}
}
public static void main(String[] args) {
CRC162 c = new CRC162();
int[] arr = new int[]{0xFC, 0x05, 0x11};
System.out.println(Integer.toHexString(c.ComputeChecksum(arr)));
}
- Je obtenir ce 521
Espère que quelqu'un pourra m'aider. J'en ai besoin pour la communication avec l'appareil à l'aide de ID003 protocole.
EDIT:
À l'aide de ce calculateur en ligne à http://www.lammertbies.nl/comm/info/crc-calculation.html pour l'entrée FC0511-je obtenir 0x2756 droit de CRC-CCITT (Kermit).
Je ne suis pas sûr du tout, j'ai trouvé cette fonction sur stackoverflow et javaranch forums.
Je pense qu'il y a un problème de définition : la représentation du CCITT-CRC est effectivement x^16 + x^12 + x^5 + 1, mais cela donne 0x1021 et pas 0x1081 (source Wikipédia sur CRC
Il semble qu'il y a beaucoup de variantes de CRC ... Êtes-vous sûr de ce que vous voulez, c'est que pour ce tableau [0xFC] [05] [11] le résultat doit être [27] [56]. Parce que, selon les progs sur la page lammertbies.nl/comm/info/crc-calculation.html, il n'est pas la norme CCITT CRC, mais le Kermit variante.
selon reveng.sourceforge.net/crc-catalogue/16.htm, Kermit variante est le "vrai" CCITT-CRC.
OriginalL'auteur AdrianES | 2014-07-11
Vous devez vous connecter pour publier un commentaire.
Voici une autre version de Kermit la CRC. Celui-ci est une traduction directe de l'codes C dans http://www.lammertbies.nl/comm/info/crc-calculation.html. L'optimisation est qu'un tableau de valeur CRC pour n'importe quel octet est pré-calculé au chargement des classes, et donc le reste de la CRC calculs est beaucoup plus simple.
La sortie est prévue :
OriginalL'auteur Serge Ballesta
x^16 + x^12 + x^5 + 1 n'est pas 0x1081. Il est 0x1021. x^5 est de 20, pas 80. (Notez que le x^16 est supprimé.)
En outre, Kermit CRC que vous avez besoin est réfléchie, de sorte que le polynôme est inversée donnant 0x8408.
Pour ce CRC, vous initialiser à zéro et ne pas compléter le résultat.
Donc la modification de votre premier exemple en conséquence, il calcule ce que vous voulez:
N'a pas d'importance. Si l'autre extrémité, à l'aide d'un CRC comme ça, alors vous devez ainsi.
peut-être que si les deux parties acceptent d'utiliser exactement le même code de base sur le processeur similaire, mais ce n'est pas très pratique. Dans la pratique (en particulier dans l'automobile) de nombreux modules venus de différents fournisseurs et attendre CCITT-CRC16 retour à la conformité de la valeur dans ces situations, et si vous utilisez la non-conformité de la mise en œuvre, alors il n'importe. C'est assez bien connue dans l'industrie de l'automobile des cercles.
Désolé, je ne pouvais pas analyser cela.
OriginalL'auteur Mark Adler
Fonctionne pour les deux ASCII et HEX calcul.
De sortie:
CRC-CCITT (XModem) Ascii: 87F4
CRC-CCITT (0xFFFF) Ascii: 763A
CRC-CCITT (0x1D0F) Ascii: 9F86
CRC-CCITT (XModem) Hex: 57FF
CRC-CCITT (0xFFFF) Hex: D33F
CRC-CCITT (0x1D0F) Hex: 59EF
Solution est basée à partir de l'échantillon trouvé dans l'université de princeton http://introcs.cs.princeton.edu/java/61data/CRC16CCITT.java
OriginalL'auteur Jan Bobis
Ce n'est pas le mien, mais il a travaillé parfait pour moi, "DatatypeConverter" est quelque chose que j'ai déjà dans mon proyect. C'est un véritable exemple pour moi et les œuvres.
OriginalL'auteur Leandro S