Portal    Foro    Buscar    FAQ    Registrarse    Conectarse


Publicar nuevo tema  Responder al tema 
Página 1 de 1
 
 
Códigos De Comprobación CRC
Autor Mensaje
Responder citando   Descargar mensaje  
Mensaje Códigos De Comprobación CRC 
 
Este es un código CRC que sirve para calcular el CRC de un determinado mensaje.
Es capaz de utilizar cualquier CRC aunque he probado los normalizados.

Existe en la base de conocimientos un texto sobre el uso de estos códigos
'---------------------------------------------------------------------
' función que calcula el CRC de un mensaje.
' Parámetros de entrada:
'   Mensaje --> El mensaje.
'   Polinomio --> Polinomio generador. en formato hexadecimal
'   CheckCrc --> Si se da es porque se desea comprobar. En este caso
'                el resultado debe ser cero
' Salida:
'   Crc --> El crc calculado en formato string-binario o si era una
'           comprobación devolverá 0 si es correcto y otra cosa si no
'           lo es
' ---------------------------------------------------------------------------------------------------

PUBLIC FUNCTION CalcularCrc(Mensaje AS String, Polinomio AS String, OPTIONAL CheckCrc AS String) AS String
DIM GradoPolinomio AS Integer, Resto AS String, ElCrc AS String

'Quitar al polinomio los ceros no significativos a la izquierda
Polinomio = QuitarCerosPolinomio(Polinomio)
'El polinomio se recibe en hexadecimal. Convertirlo a binario
Polinomio = ConvertirABin(Polinomio)

'Obtener el grado del polinomio
GradoPolinomio = ObtenerGradoPolinomio(Polinomio) 'Obtener el grado del polinomio generador

IF CheckCrc THEN
  'anexar el crc a comprobar
  Mensaje &= CheckCrc
ELSE
  'Agregar tantos ceros a la derecha al mensaje como sea el grado del polinomio
  Mensaje = AgregarCeros(Mensaje, GradoPolinomio)
ENDIF

'Obtener resultado
resto = DividirModuloDos(Mensaje, polinomio) 'efectuar división binaria
Elcrc = Right(resto, GradoPolinomio)
RETURN ElCrc
END

La función previa hace dos cosas. Una es recibir como parámetros el mensaje sobre el que calcular el CRC y el polinomio a utilizar. En este caso calcula el CRC correspondiente.
La segunda cosa es comprobar un CRC manualmente. En este caso la función recibe el mensaje, el polinomio y el CRC a comprobar. En este caso la función retornará 0 si el CRC es correcto y otra cosa si el CRC no es correcto.


Esta es la función que calcula la división entera de dos polinomios. Existe un texto en la base de conocimientos que explica su funcionamiento.
'función que realiza la división entera de dos polinomios
' par ámetros de entrada:
'   Dividendo - - > polinomio a dividir
'   Divisor - - > polinomio divisor
' Salida:
'   El resto de la división
PRIVATE FUNCTION DividirModuloDos(Dividendo AS String, Divisor AS String) AS String
  
  DIM PosIni AS Integer = 1 'en un string de bytes posini indica el primer bit que debe ser xoreado si toca hacerlo
  DIM Resto AS String = dividendo, NumDivisiones AS Integer = Len(Dividendo) - Len(divisor)
  
  DO WHILE PosIni < NumDivisiones
    'si el primer bit es 1 dividir y quedarse con el resto
    IF Mid(Resto, PosIni, 1) = "1" THEN  'Si el primer dígito a operar es 1 y por tanto hay que hacer xor
      resto = hacerxor(resto, divisor, posini) 'Hacer XOR a bits correspondientes y obtener el resultado
    ENDIF
    INC PosIni
  LOOP    'ir a siguiente bit que tendrá que ser operado para xor si corresponde
  RETURN resto 'devolver el resto de la división
END


Esta es la función que realiza XOR bit a bit entre dos string
'función que realiza xor de GradoPolinomio bits en los datos a partir del bit indicado en PosIni
PRIVATE FUNCTION hacerxor(Resto AS String, Divisor AS String, PosIni AS Integer) AS String
  
  DIM contador AS Integer, s AS String 's=resultado de la operación tras el xor
  DIM ByteResto AS String, ByteDivisor AS String, ByteResultado AS Byte
  
  'Incluir en el resultado los bytes de la izquierda que no voy a xorear.
  s = Left(Resto, PosIni - 1)
  'Los bytes que voy a xorear son siempre left(Resto,Len(divisor) + PosIni - 1)
  FOR contador = 1 TO Len(Divisor) 'recorrer los bits a operar
    byteResto = Mid(Resto, PosIni + Contador - 1, 1)
    byteDivisor = Mid(Divisor, Contador, 1)
    ByteResultado = IIf(byteResto = byteDivisor, 0, 1)
    s &= CStr(ByteResultado) 'almacenar resultado
  NEXT  
  'Los restantes son siempre mid(Resto,len(divisor)+PosIni) y no van a ser operados en este cicle
  s &= Mid(Resto, Len(divisor) + PosIni) 'añadir los bits que no he xoreado
  RETURN s
END


Esta es la función que sirve para multiplicar un polinomio por X. Lo que se hace es añadir X ceros por la derecha.
'Función que multiplica un polinomio. Agrega GradoPolinomio ceros por la derecha
PRIVATE FUNCTION AgregarCeros(t AS String, G AS Integer) AS String
  
  t &= String(g, "0")
  RETURN t
END


Esta es la función que recibe un polinomio y calcula su grado. Deben haberse eliminado previamente los bits no significativos (ceros a la izquierda)
'Función que obtiene el grado de un polinomio. El bit mas significativo es 1.
PRIVATE FUNCTION ObtenerGradoPolinomio(p AS String) AS Integer
  RETURN Len(p) - 1
END


Esta es la función que recibe un polinomio y le quita los bits no significativos (quita los ceros a la izquierda)
' función que recibe un polinomio y le quita los ceros no significativos
PRIVATE FUNCTION QuitarCerosPolinomio(p AS String) AS String  
DIM pos AS Integer = InStr(p, "1")
  p = IIf(pos > 0, Mid(p, pos), "0")
  RETURN p  
END


Esta es la función que recibe un polinomio en formato hexadecimal y lo convierte a binario
PUBLIC FUNCTION ConvertirABin(s AS String) AS String
DIM valor AS String
  valor = Bin(Eval("&H" & s & "&"))  
  RETURN valor
END


Esta última función no forma parte de las anteriores. La agrego porque me resuttó útil para las comprobaciones porque comprobar en binario esos chorizos de unos y ceros se hace complicado. Lo que hace es coger un valor binario y devolverlo en hexadecimal
PUBLIC FUNCTION ConvertirAHex(s AS String) AS String
DIM Contador AS Integer, Resultado AS String
resultado = Hex(Eval("&x" & s & "&"))
RETURN resultado
END

Es útil si se quiere escribir el CRC calculado en un textbox o donde sea. En vez de escribir un chorizo binario escribe un valor hexadecimal mas comprensible.
 



 
última edición por soplo el Domingo, 13 Marzo 2011, 16:23; editado 1 vez 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Códigos De Comprobación CRC 
 
Comprobar un CRC
Para comprobar un CRC se necesita el código anterior que lo calcula.
Para comprobar un CRC es necesario conocer el polinomio generador que se utilizó para calcularlo.
Un CRC viene anexado a un determinado mensaje por lo que normalmente nosotros recibimos un paquete que contiene por ejemplo veinte bytes y sabemos que estamos usando un CRC-32 sabemos que el CRC-32 es un CRC de 32 bits osea cuatro bytes.
Osea que el mensaje es de 16 bytes y los cuatro últimos son el CRC.

Asi que separamos ambar partes y luego utilizamos el código anterior para comprobar el CRC.

En la base de conocimientos hay un texto que explica esto.
'---------------------------------------------------------------------------------------------------
' función que calcula el CRC de un mensaje.
' Parámetros de entrada:
'   Mensaje --> El mensaje. Si no se incluye ElCrc se supone que el Crc forma parte del mensaje
'    ElCrc - - > si se incluye el mensaje es limpio y no incluye crc
'    Polinomio --> polinomio generador. Se entrega en formato hexadecimal.
' Salida:
'   True --> los datos y el Crc coinciden. False --> no coinciden
' ---------------------------------------------------------------------------------------------------
PUBLIC FUNCTION ComprobarCrc(Mensaje AS String, Polinomio AS String, OPTIONAL ElCrc AS String) AS Boolean
DIM Resultado AS String, CrcOk AS Boolean, GradoPolinomio AS Integer
'msg="11010011101100"   polinomio="10001000000100001"
'obtener el polinomio
'polinomio = ConvertirABin(polinomio)
GradoPolinomio = ObtenerGradoPolinomio(ConvertirABin(Polinomio))
    
IF NOT Elcrc THEN 'si no se envió un crc
  ElCrc = Right(Mensaje, GradoPolinomio)
  Mensaje = Left(mensaje, Len(Mensaje) - Len(ElCrc))
ENDIF

Resultado = CalcularCrc(Mensaje, polinomio, ElCrc)
CrcOk = IIf(CLong(Resultado) = 0, TRUE, FALSE)
RETURN CrcOk  
  
END

 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Códigos De Comprobación CRC 
 
Los polinomios CRC estandar son:
PRIVATE CONST CRC_1 AS String = "3" 'bit de paridad
PRIVATE CONST CRC_4_ITU AS String = "13"
PRIVATE CONST CRC_5_EPC AS String = "29"
PRIVATE CONST CRC_5_ITU AS String = "35"
PRIVATE CONST CRC_5_USB AS String = "25"
PRIVATE CONST CRC_6_ITU AS String = "43"
PRIVATE CONST CRC_7 AS String = "89"
PRIVATE CONST CRC_8_CCITT AS String = "107"
PRIVATE CONST CRC_8_Dallas_Maxim AS String = "131"
PRIVATE CONST CRC_8 AS String = "1D5"
PRIVATE CONST CRC_8_SAE_J1850 AS String = "11D"
PRIVATE CONST CRC_8_WCDMA AS String = "19B"
PRIVATE CONST CRC_10 AS String = "633"
PRIVATE CONST CRC_11 AS String = "B85"
PRIVATE CONST CRC_12 AS String = "180F"
PRIVATE CONST CRC_15_CAN AS String = "C599"
PRIVATE CONST CRC_16_IBM AS String = "18005"
PRIVATE CONST CRC_16_CCITT AS String = "11021"
PRIVATE CONST CRC_16_T10_DIF AS String = "18BB7"
PRIVATE CONST CRC_16_DNP AS String = "13D65"
PRIVATE CONST CRC_16_DECT AS String = "10589"
PRIVATE CONST CRC_24 AS String = "15D6DCB"
PRIVATE CONST CRC_24_Radix_64 AS String = "1864CFB"
PRIVATE CONST CRC_30 AS String = "6030B9C7"
PRIVATE CONST CRC_32_IEEE_802_3 AS String = "104C11DB7"
PRIVATE CONST CRC_32_C_Castagnoli AS String = "11EDC6F41"
PRIVATE CONST CRC_32_Koopman AS String = "1741B8CD7"
PRIVATE CONST CRC_32Q AS String = "1814141AB"
PRIVATE CONST CRC_40_GSM AS String = "10004820009"

 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Códigos De Comprobación CRC 
 
Redirijo el comentario a la sección del foro sobre controles y programación.

Esto no debería ir aquí.
 



 
última edición por viejito el Jueves, 18 Diciembre 2014, 05:18; editado 1 vez 
viejito - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Mostrar mensajes anteriores:    
 
OcultarTemas parecidos
Tema Autor Foro Respuestas último mensaje
No hay nuevos mensajes Códigos De Escape ljma Aplicaciones/Fragmentos de Código 1 Lunes, 27 Diciembre 2010, 11:24 Ver último mensaje
ljma
No hay nuevos mensajes Estimado Forero Que Copias Códigos soplo Sobre Gambas-es 1 Lunes, 17 Enero 2011, 19:24 Ver último mensaje
fabianfv
No hay nuevos mensajes Gestor Códigos QR jsbsan Aplicaciones/Fragmentos de Código 7 Lunes, 13 Febrero 2012, 02:41 Ver último mensaje
clsource
No hay nuevos mensajes Códigos Postales De España Gambas seta43 Aplicaciones/Fragmentos de Código 0 Sabado, 28 May 2016, 07:22 Ver último mensaje
seta43
 

Publicar nuevo tema  Responder al tema  Página 1 de 1
 

Usuarios navegando en este tema: 0 registrados, 0 ocultos y 1 invitado
Usuarios registrados conectados: Ninguno


 
Lista de permisos
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas
No puede adjuntar archivos
Puede descargar archivos
No puede publicar eventos en el calendario



  

 

cron