aboutsummaryrefslogtreecommitdiff
path: root/src/Utils.py
blob: 3618dfdbcc41ba013d4d960ba834dc9ca53c22f1 (plain)
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
# -*- coding: iso-8859-1 -*-

###############################################################################
##### fichier contenant la classe en charge du                  ###############
##### calcul du CRC CCITT16                                     ###############
###############################################################################

# imports des modules python a utiliser
import os

# declaration des constantes à utiliser pour travail sur les bits
CRC_POLYNOMIAL = 0x00102100
TAIL_CANCELLING_MASK = 0xFFFFFF00
HEADER_TAIL_CANCELLING_MASK = 0x00FFFF00
LSB_HEADER_TESTING_MASK = 0x01000000
NULL_VALUE = 0x00000000
REMAINDER_CANCELLING_MASK = 0xFF0000FF
INIT_VALUE = 0x00FFFF00

##
# classe CalcCRC
# cette classe permet de calculer une CRC CCITT sur 16 bits à partir d'une string
#
class CalcCRC:

    ##
    # initialisation des polynomes de controles
    #
    def __init__(self):
        self.CRC_POLYNOMIAL = 0x00102100
        self.cancellingMask = 0xFFFFFF00
        self.testingMask = 0x01000000
        self.value = 0x00000000
    
    ##
    # methode decalageGauche
    # methode effectuant un decalage a gauche des bits de l'attribut value 
    # le bit de poids le plus fort de tail va dans le bit de poid faible de remainder et le bit de poids fort de remainder 
    # dans le bit de poids faible du header
    #
    def decalageGauche(self):
        self.value = self.value << 1
    
    ##
    # methode insertNewValue
    # methode permettant d'ajouter a la fin de value la valeur du nouvel octet
    # @param byteValue : nouvel octet à mettre à la fin de l'attribut value
    #
    def insertNewValue(self, byteValue):
        intermediaire = self.value & TAIL_CANCELLING_MASK
        self.value = intermediaire | byteValue
    
    ##
    # methode remainderDivision
    # methode effectuant la division du reste par le polynome de controle
    #
    def remainderDivision(self):
        intermediaire = self.value
        intermediaire = intermediaire & HEADER_TAIL_CANCELLING_MASK
        intermediaire = intermediaire ^ CRC_POLYNOMIAL
        intermediaire = intermediaire & HEADER_TAIL_CANCELLING_MASK
        nullRemainder = self.value & REMAINDER_CANCELLING_MASK
        self.value = intermediaire | nullRemainder
    
    ##
    # methode calcCCITTCRC16
    # methode calculant le CRC d'un message ASCII et le retournant
    # @param message : message dont on veut calculer le CRC
    # @return la valeur du CRC
    #
    def calcCCITTCRC16(self, message):
        # initialisation de la variable de calcul
        self.value = INIT_VALUE
        # pour chaque octet du message effectue le calcul du CRC
        for value in message :
            self.calcCRC(ord(value))
        
        self.calcCRC(0x00)
        self.calcCRC(0x00)
        
        return (self.value & HEADER_TAIL_CANCELLING_MASK) >> 8
    
    ##
    # methode calcCRC
    # methode calculant le reste de la division polynomial
    # @param byteValue : nouvel octet 
    #
    def calcCRC(self, byteValue):
        # on range la nouvelle valeur dans le registre de calcul self.value
        self.insertNewValue(byteValue)
        
        # on effectue la division
        for test in range(8):
            self.decalageGauche()
            if (self.value & LSB_HEADER_TESTING_MASK) != NULL_VALUE :
                self.remainderDivision()
            else :
                pass
        
                
if __name__ == '__main__':
    message = 'A'
    crcCalculator = CalcCRC()
    crcCalculator.calcCCITTCRC16(message)