Convertir código C++ a Delphi (para lograr un cierto "CRC" de una cadena de entrada)
Hola a todos,
Me han encargado cierta tarea para la que no parezco estar capacitado... creo que el código C++ que me han pasado debería ser más completo, en todo caso, pero, como no controlo C++... tampoco sé hasta qué punto algunas partes del código pueden deducirse, por decirlo así... El código en cuestión es el siguiente: Código:
Cita:
Hay cosas que se me escapan, como la variable "x", que, entiendo que es la posición / caracter, de la variable "data". De este modo, he conseguido armar el siguiente código... que ya me sorprende que compile... y se ejecute sin errores aparentes...
Sin embargo, el resultado que obtengo en "CRC", es 30841, o sea, no 5320. Por otro lado, si no inicializo la variable CRC, es decir, el siguiente código:
... sigo sin obtener el resultado esperado... en fin... reconozco que estoy perdido: porque no sé si estoy traduciendo el código C++ en condiciones (diría que no), porque, o sé siquiera cómo es que se puede ejecutar el código Delphi mostrado sin errores... y, finalmente, porque no sé si es que el código que me han dado para traducir... en realidad no puede traducirse, puesto que falten datos... ¿Alguna posible ayuda? :rolleyes: ¡Muchísimas gracias de antemano! :o |
El código en C tiene cosas que faltan.
1. crc debe estar inicializado. 2. Si asumimos la cadena como "estilo C", x debe inicializarse a 0. 3. Asumimos que count el la longitud de la cadena pero debería estar en el código y su cálculo correspondiente. 4. Tampoco sabemos si la cadena es unicode. Con el código C preparado de esta forma, el resultado es 17940: Código PHP:
La traducción equivalente a delphi usando String, devuelve el mismo resultado (17940):
Alcaraciones sobre la traducción: 1. Las cadenas delphi empiezan el indice = 1; en C comienzan en 0 2. x++ significa que tras las evaluaciones/operaciones se incrementará x 3. --i significa que i de decrementa antes que cualquier otra cosa que de haga con i (por ello uso repeat - until decrementando i consiguiendo una traducción casi literal) y por lo mismo cambio el límite de count en su bucle. Conclusión: ambos códigos arrojan el mismo resultado y "algo" falta en la inicialización de las variables, probablemente en crc Saludos. |
Cita:
No te han dicho que algoritmo de crc usan? Nota: Y usando https://crccalc.com/ no da con ninguno de los algoritmos comunes. |
Cita:
Pero faltan datos de inicialización del CRC para que de el resultado esperado. Saludos. |
Hola a todos,
Qué puede uno decir... ya sabía yo (incluso asumía) que iban a tratar de echarme una mano... ¡desde luego si el ClubDelphi no existiera habría que inventarlo! Con todos vosotros en el mismo, claro. :) Ya he informado a quien me encargó la tarea que, aparentemente, algo falta en el código... puesto que no es posible obtener la misma salida de la entrada proporcionada a modo de ejemplo. Ciertamente, se me pasó comentar aquí que ofrecieron algo de documentación: http://srecord.sourceforge.net/crc16-ccitt.html ... sin embargo, no lo comenté, porque, buscando información sobre este algoritmo en concreto, conseguí cierta ayuda a través de StackOverflow (y el inefable Remy Lebeau), pero, resulta que ocurría lo propio: de la misma entrada, no se obtenía la misma salida... empero, el algoritmo está bien implementado, por lo que se ve, por los ejemplos de entrada y salida que se ofrecen en la propia documentación, que, en este caso sí parecen coincidir. De modo que pensé que acaso no había que seguir esa documentación al pie de la letra, sino que, en realidad el cálculo del CRC en cuestión no seguía esa documentación (aunque curiosamente la enlazaban...) sino que era sólo el código C++ que nos habían dado a modo de ejemplo. Empero, como se ha visto, este código no produce la salida esperada... Y yo de mí no me fiaba, de mi traducción a Delphi, quiero decir, pero, de la vuestra me fío, de modo que, algo raro hay aquí... Os mantendré informado sobre este asunto, a ver en qué queda todo, y, una vez más, ¡muchísimas gracias por vuestra ayuda! |
Por si te sirve de ayuda, inicializando crc = 3077 da el resultado esperado.
Saludos. |
Hola a todos,
Cita:
|
Cita:
A favor de 3077 (0C06h) es que es el único número de 0 - 65535 que consigue que CRC sea 5320 para el algoritmo implementado Saludos. |
Hola a todos,
Cita:
|
Dec, ¿Cual versión de Delphi estas utilizando?. Al migrar algoritmos similares desde Delphi 5 a Delphi XE3 ha sido necesario cambiar el tipo de datos de la variable que contiene la DATA de "String" a "AnsiString".
PostData: Ya hice la prueba y en este caso el cambiar a Ansistring no afecta el comportamiento. |
Hola David.
Aunque tarde, por que ya el trabajo está hecho, te pongo los códigos que usé para mis pruebas. C++ Código PHP:
Saludos :) |
Cita:
La versión C++ funciona Ok pero la delphi tiene un pequeño error. El bucle principal debe ser:
Esto se debe a que en la versión C primero decrementa y en la delphi es después. Posiblemente ha sido que has publicado un código no terminado en lugar del final. Saludos. |
Hola escafandra.
Fijate que en la línea en que obtengo la longitud de cadena hago uso de la función Pred. Dado el valor 3077, tanto la versión de C++ como la de Delphi 10.3 arrojan el resultado 5320. Saludos :) |
^\||/ Correcto.
Saludos. |
Hola a todos,
Cita:
Gracias de nuevo a todos, ecfisa, escafandra, mamcx, en efecto, estoy esperando a ver qué me dicen sobre la necesidad de inicializar la variable "crc" con el valor "3077"... pues de otra forma no parece obtenerse el valor apropiado. Sea como sea, estoy seguro de que algo falla / falta en el código de ejemplo que me ofrecieron, es decir, vosotros no falláis, eso lo tengo claro: de modo que veremos a ver en qué queda todo esto. ¡En cuanto me digan algo lo publico aquí! :) |
Hola a todos,
Por fin he conseguido más información sobre el tema que se trata aquí... y ahora estoy seguro de que es posible convertir el código a Delphi, vaya, de que vosotros sabréis hacerlo, puesto que yo, aunque lo he intentado... no he sido capaz... :( En efecto, el código de que se partía al principio no estaba completo, sino que faltaba información, según lo veo yo, principalmente, los tipos de las variables de entrada y de salida, o bien podía deducirse todo del siguiente código... que es el "programa" completo: Código:
using System; Desde ya os agradezco vuestra ayuda a todos. :rolleyes: |
Hola a todos de nuevo,
Quería añadir... que, en este caso, es importante tener en cuenta que la versión de Delphi habrá de ser la Delphi 2007... por si hay que tenerlo en cuenta... :rolleyes: |
Hola a todos,
Aquí los intentos que llevo a cabo, usando tanto el código de escafandra como el de ecfisa, dando ambos el mismo resultado: 22586, pero, no el esperado: 5320, la madre que le parió. :eek: :D
|
Hola David.
A ver si entendí bien, ¿ El resultado esperado es 5320 ? por que de ser así el codigo que probé anteriormente me da ese resultado, no obtengo el valor 22586. Saludos :) |
Traducción cuasi literal:
Uso:
Consideraciones: 1. En C un array de Char es una cadena. Un unsigned char es un BYTE. Con estas consideraciones y teniendo en cuenta que se introduce una cadena, podemos usar PAnsyChar como parametro de entrada. Tambien podríamos unsa un array de bytes pero requeriría casting de entrada. 2. el CRC es un word pasado a array de 2 Bytes. El resultado del word es 8275 que en hexadecimal es $2053 pero visto como array de bytes es $53, $20 Saludos. |
Hola a todos,
Cita:
¡Gracias, ecfisa, por tu ayuda! |
Hola a todos,
¡ecfisa! A ver si lo que has probado ha sido el código de scafandra... :D :D ¡escafandra! En efecto, tú código produce el resultado esperado, empero, fíjate cómo obtengo yo el resultado "para mostrarlo"... no sé si es la forma más adecuada... aunque parece funcionar, es decir, obtengo el tan deseado 5320... como una cadena...
Me queda la duda de que esa sea la mejor forma de obtener finalmente el valor 5320... pero está claro que os debo una... sino dos... porque me habéis salvado de esta tarea: ahora sólo queda implementarlo dentro de un plugin que a su vez será usado en el programa que necesita calcular el CRC de marras... Sin vosotros me hubiera sido imposible... y es que uno está muy falto de conocimientos, o, al menos, de los conocimientos que aquí sin duda eran necesarios. Espero poder responderos de alguna manera en otra ocasión, aunque, con vuestro nivel... tendrá que ser invitándoos a un refrigerio. :) |
Hola a todos,
He dicho arriba que me quedaba la duda de si sería o no lo más correcto usar "IntToHex" para obtener el resultado como una cadena. Mayormente, me lo preguntaba porque si probaba con otra cadena de entrada, obtenía resultados del tipo: 1B07, es decir, no numéricos, es decir, no como: 5320. No sé si será la mejor forma usar "IntToHex", pero, no se me había ocurrido probar con el programa en C++... y, en efecto, este también produce resultados del tipo: 1B07, de modo que, asumo que, aunque "IntToHex" no sea acaso lo mejor, lo cierto es que parece funcionar... al menos tal como lo hace el programa en C++. En fin, ya tengo todo esto (la función de escafandra) dentro del "plugin" en el que tenía que ir. :) ¡Muchas gracias de nuevo por vuestra ayuda! |
La forma de representarlo en texto debe ser con IntToHex, el problema es que quizás el dato de deba manejar como array de Bytes y no como texto. Eso quiere decir que quizás deberías devolver el resultado CRC como Bytes y preparar una función para pasar a texto cuando proceda. Así lo tienes todo cubierto.
Saludos. |
Hola a todos,
Cita:
* El problema es que esto tiene que implementarse en NeoBook, cierto programa para Windows (desarrollado con Delphi, por cierto), más concretamente como un plugin de este programa, y, ahí no existen tipos como "byte", todo son cadenas o números. Pero bueno, no voy a adelantar acontecimientos... el resultado del programa de C++ es el mismo ahora que en Delphi: tal vez con esto sea suficiente. ¡Muchas gracias de nuevo a todos por vuestra ayuda! :) |
La franja horaria es GMT +2. Ahora son las 19:03:13. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi