modulo para calcular crc y solicitud de ayuda para hacer fuerza bruta

Tny a.porrua en gmail.com
Lun Sep 25 15:00:42 CEST 2006


Hola pitonisos :)

Necesitaba un módulo para calcular crcs en python y como no encontré 
ninguno que me satisfaciera (o supiera utilizar) hice uno, que pongo a 
disposición de quien lo quiera.

Otra cosa, trabajo para una empresa que hace programas y mantenimiento 
de parkins, y tenemos que sustituir lso equipos y programas de S&B, el 
problema es que tenemos que emplear sus periféricos, (lectores, 
impresores de tickets y demás)  sospechamos que empelan un crc de 16 
bits del que desconocemos su polinomio, y posibles bytes iniciales y 
xors finales.
He hecho un script en python que supongo me dara la solución en una o 
dos semanas.
Si algunas personas de la lista fuesen tan amables de colaborar 
obtendría la solución mucho antes.

Aquellos que quieran ayudarme que se pongan en contacto connmigo en mi 
correo (para no interferir en la lista) para que pueda repartir la 
fuerza bruta en tre todos.

Gracias


El módulo para calcular crc de 16 bits.
Disponed de él como os de la gana, (usandolo, modificandolo, 
estudiandolo, u criticandolo )

Saludos

# -*- coding: cp1252 -*-
#Tny 20/09/2006 Oviedo
def tablas(polinomio):
    "Devuelve la tabla para proccesar byte a byte para un polinomio dado"
    polinomio=polinomio | 0x10000                               # este 
bit siempre vale 1 en crcs de 16 bits
    p1=polinomio>>9                                             #p1 son 
los 8 bits que afectan al primer byte
    p2=polinomio>>1                                             #p2 son 
los 16 bis que afectan al segundo byte
    p3=(polinomio&255)<<7                                       #p3 son 
los 8 bits que afectan al tecer byte
    
    supertabla=[]                                               #declaro 
la lista
    for i in xrange(256):                                       #los 
valores que puede tomar un byte van desde 0 hasta 255
        n=i                                                     #para 
poder operar sobre el valor de i sin tocar a i
        elemento2=0                                             
#elemento2 y 3 inician a 0
        elemento3=0
        for j in xrange(8):                                     #8 bits 
por byte
            if n & 2**(7-j):                                    #si en n 
esta activo el bit (7-j) van numeraos al reves
                n=n ^ p1>>j                                     
#aplicamos a n el xor que le toca
                elemento2=elemento2 ^ ((p2>>j)&255)             #" a 
elemento2 "   "   "   "   "
                elemento3=elemento3 ^ ((p3>>j)&255)             #" a 
elemento3 "   "   "   "   "
        supertabla.append((elemento2,elemento3))                
#añadimos a la tabla la tupla (elemento2, elemento3) n no nos importa 
despues de ser procesado siempre vale 0
    return supertabla                                           # sin 
comentarios ;)

def crc(texto,polinomio=0x1021,inicial=0xffff,final=0x0000):
    "calcula el crc de txt para el polinomio poly"
    tabla=tablas(polinomio)                                     #obtengo 
las tablas para el polinomio   
    x1,x2=tabla[inicial>>8]                                     #x1 es 
el xor a aplicar al siguiente byte, x2 es el xor a aplicar al 
posiguiente (inventando palabros :P)
    x1,x3=tabla[(inicial&255)^x1]                               #aplico 
x1 al siguiente, y obtengo x1 para aplicar al siguiente, y x3 para el 
posiguiente
    x1^=x2                                                      #x1^x2 
es el x1 que aplicaré la proximavez
    x2=x3                                                       #meto x3 
en x2 para no machacarlo
    for i in xrange(0,len(texto)):                              #recorro 
todo el texto
        x1,x3=tabla[ord(texto[i])^x1]                           
#actualizo los valores de x1,x2 y x3
        x1^=x2
        x2=x3
    return chr(x1^(final>>8)) + chr(x2^(final&255))             #(x1,x2) 
^ final es el crc

class Crc:                 # la función genera las tablas cada vez que 
es llamada, por lo que para hacer varios crcs con el mismo polinomio se 
aconseja usar este objeto
    def __init__(self,polinomio=0x1021,inicial=0xffff,final=0x0000):
        "Crea un objeto Crc"
        self.inicial=inicial
        self.final=final
        self.polinomio=polinomio
    def __call__(self,texto):
        "Devuelve el crc del texto dado"
        x1,x2=self.tabla[self._inicial[0]] #el código es el mismo que el 
de la función
        x1,x3=self.tabla[self._inicial[1]^x1]
        x1^=x2
        x2=x3
        for i in xrange(0,len(texto)):
            x1,x3=self.tabla[ord(texto[i])^x1]
            x1^=x2
            x2=x3
        return chr(x1^self._final[0]) + chr(x2^self._final[1])
    def __setattr__(self,name,value):
        self.__dict__[name] = value
        if name=="inicial":
            self.__dict__["_inicial"]=(value>>8,value&255)
        elif name=="final":
            self.__dict__["_final"]=(value>>8,value&255)
        elif name=="polinomio":
            self.__dict__["tabla"]=tablas(value)
    def __str__(self):
        return "("+hex(self.polinomio)+","+hex(self.inicial)+")"




Más información sobre la lista de distribución Python-es