Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-02-2020
orodriguezca orodriguezca is offline
Miembro
 
Registrado: ene 2009
Posts: 221
Poder: 16
orodriguezca Va por buen camino
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.

Última edición por orodriguezca fecha: 18-02-2020 a las 20:06:35.
Responder Con Cita
  #2  
Antiguo 18-02-2020
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
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:
...
#define USHORT unsigned short
...

int crc16(const string &dataUSHORT crc)
{
  
USHORT x(0);
  
int count data.length();

  while (--
count >= 0)
  {
    
USHORT z = (USHORT)(data[x++] << 8);
    
crc = (USHORT)(crc z);
    for(
int i 80; --i)
      
crc = (crc 0x8000) ? (USHORT)(crc << 0x1021) : (USHORT)(crc << 1);
  }
    return 
crc;
}

void main()
{
  
string data "13|0000123|1|Maximilian|Mustermann|05051999|21092019";

  
cout <<  crc16(data3077) << endl
Delphi:
Código Delphi [-]

function Crc16(const data: string; crc: Word): Word;
var
  x, z: Word;
  count, i: Integer;
begin
  count := Pred(data.Length);
  x     := 0;
  while (count >= 0) do
  begin
    Dec(count);
    Inc(x);
    z   := Word(data[x]) shl 8;
    crc := crc xor z;
    for i := 7 downto 0 do
      if crc and $8000 <> 0 then
        crc := (crc shl 1 xor $1021)
      else
        crc := (crc shl 1);
  end;
  Result := crc;
end;

...
var
  data : string;
begin
  data :=  '13|0000123|1|Maximilian|Mustermann|05051999|21092019';
  ShowMessage(Crc16(data,3077).ToString);
end;

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 18-02-2020 a las 20:57:02.
Responder Con Cita
  #3  
Antiguo 18-02-2020
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por ecfisa Ver Mensaje
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:
...
#define USHORT unsigned short
...

int crc16(const string &dataUSHORT crc)
{
  
USHORT x(0);
  
int count data.length();

  while (--
count >= 0)
  {
    
USHORT z = (USHORT)(data[x++] << 8);
    
crc = (USHORT)(crc z);
    for(
int i 80; --i)
      
crc = (crc 0x8000) ? (USHORT)(crc << 0x1021) : (USHORT)(crc << 1);
  }
    return 
crc;
}

void main()
{
  
string data "13|0000123|1|Maximilian|Mustermann|05051999|21092019";

  
cout <<  crc16(data3077) << endl
Delphi:


Código Delphi [-]
function Crc16(const data: string; crc: Word): Word;
var
  x, z: Word;
  count, i: Integer;
begin
  count := Pred(data.Length);
  x     := 0;
  while (count >= 0) do
  begin
    Dec(count);
    Inc(x);
    z   := Word(data[x]) shl 8;
    crc := crc xor z;
    for i := 7 downto 0 do
      if crc and $8000 <> 0 then
        crc := (crc shl 1 xor $1021)
      else
        crc := (crc shl 1);
  end;
  Result := crc;
end;

...
var
  data : string;
begin
  data :=  '13|0000123|1|Maximilian|Mustermann|05051999|21092019';
  ShowMessage(Crc16(data,3077).ToString);
end;


Saludos



La versión C++ funciona Ok pero la delphi tiene un pequeño error. El bucle principal debe ser:
Código Delphi [-]
while (count > 0)

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.
Responder Con Cita
  #4  
Antiguo 19-02-2020
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
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
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 19-02-2020 a las 05:23:27.
Responder Con Cita
  #5  
Antiguo 19-02-2020
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Correcto.

Saludos.
Responder Con Cita
  #6  
Antiguo 19-02-2020
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos,

Cita:
Empezado por orodriguezca Ver Mensaje
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.
Pues llevas razón orodriguezca, interesaba saber la versión de Delphi de que se trataba y se me olvidó mencionarlo, porque, además en este caso en concreto habré de usar Delphi 2007 como un requisito, es decir, no puedo usar versiones superiores, porque lo que se piensa llevar a cabo es cierto "plugin" que funciona dentro de un programa que no permite plugins "unicode", o sea, no permite plugins hechos con versiones de Delphi superiores a la 2007.

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í!
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #7  
Antiguo 05-03-2020
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
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;
using System.Text;

namespace QRCode
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] b = Encoding.Default.GetBytes("13|0000123|1|Maximilian|Mustermann|05051999|21092019");

            byte[] crc = CCITTx1D0F(b, b.Length);

            // Podemos ver una salida = 5320, que, es la esperada para la cadena de entrada
            Console.WriteLine( $"{crc[0]:X2}{crc[1]:X2}" );

            Console.ReadLine();
        }
        
        static private byte[] CCITTx1D0F(byte[] data, int len)
        {
            int i, x = 0;
            ushort crc = 0x1D0F;
            int count = len;

            while (--count >= 0)
            {
                ushort z = (ushort)(data[x++] << 8);
                crc = (ushort)(crc ^ z);
                i = 8;
                do
                {
                    if ((crc & 0x8000) != 0)
                        crc = (ushort)(crc << 1 ^ 0x1021);
                    else
                        crc = (ushort)(crc << 1);
                } while (--i > 0);
            }
            return BitConverter.GetBytes(crc);
        }
    }
}
Como se ve, la cosa cambia... tratamos con "bytes", no con "words" o "strings", y, ahora sí, creo que podréis acaso ayudarme / convertir el código / solucionar el problema... ¡o eso espero, puesto que yo, aunque lo he intentado (¡y teniendo más de la mitad hecho!) me declaro incapaz... aunque voy a seguir intentándolo...

Desde ya os agradezco vuestra ayuda a todos.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #8  
Antiguo 05-03-2020
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
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...
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #9  
Antiguo 05-03-2020
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
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ó.

Código Delphi [-]
function StrToBytes(const Value: string): TBytes;
var
  I: integer;
begin
  SetLength(Result, Length(Value));
  Move(Value[1], Result[0], Length(Value));
end;

function WordToBytes(const Value: Word): TBytes;
begin
 SetLength(Result, 2);
 Result[0] := TBytes(@Value)[0];
 Result[1] := TBytes(@Value)[1];
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x, z: Word;
  crc: Word;
  count, i: Integer;
  Input: string;
  Data, Result: TBytes;
begin
  Input := '13|0000123|1|Maximilian|Mustermann|05051999|21092019';
  
  Data := StrToBytes(Input);

  x := 0;
  crc := $1D0F;
  count := Pred(Length(Data));
  while (count >= 0) do
  begin
    Dec(count);
    Inc(x);
    z   := Word(Data[x]) shl 8;
    crc := crc xor z;
    for i := 7 downto 0 do
      if crc and $8000 <> 0 then
        crc := (crc shl 1 xor $1021)
      else
        crc := (crc shl 1);
  end;

  Result := WordToBytes(crc);

  ShowMessageFmt('%d%d', [Result[0], Result[1]]);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  S: TBytes;
  i, x: Integer;
  z: WORD;
  CRC: WORD;
  SLength, n: Integer;
  Result: TBytes;
  Input: string;
begin
  Input := '13|0000123|1|Maximilian|Mustermann|05051999|21092019';

  S := StrToBytes(Input);

  CRC := $1D0F;
  SLength := Length(S);
  X := 1;
  while SLength > 0 do
  begin
    Z := S[X] shl 8;
    CRC := CRC xor Z;
    i:= 8;
    repeat
      if (CRC and $08000) <> 0 then
        CRC := (CRC shl 1) xor $1021
      else
        CRC := (CRC shl 1);
      dec(i);
    until i <= 0;
    Inc(X);
    Dec(SLength);
  end;

  Result := WordToBytes(CRC);

  ShowMessageFmt('%d%d', [Result[0], Result[1]]);
end;
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #10  
Antiguo 05-03-2020
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
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
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #11  
Antiguo 05-03-2020
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos,

Cita:
Empezado por ecfisa Ver Mensaje
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
¿Qué código has probado? No será ninguno de los "intentos" que yo he puesto arriba, ¿no? Me cachis... a mí me da ese 22586 y además en ambos casos... en ambos "ButtonClicks"... ¿cómo es que puede darte a ti 5320? ¿Acaso por la versión de Delphi? Yo uso (de hecho es un requerimiento en este caso) Delphi 2007.

¡Gracias, ecfisa, por tu ayuda!
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #12  
Antiguo 05-03-2020
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Traducción cuasi literal:


Código Delphi [-]
type
ABYTE = array [0..1] of BYTE;
PABYTE = ^ABYTE;

function CCITTx1D0F(data: PAnsiChar; count: integer): ABYTE;
var
  crc, z: Word;
  x, i: Integer;
begin
  crc:= $1D0F;
  x     := 0;
  while (count > 0) do
  begin
    Dec(count);
    z   := Word(data[x]) shl 8;
    Inc(x);
    crc := crc xor z;
    i:=8;
    repeat
      if crc and $8000 <> 0 then
        crc := (crc shl 1 xor $1021)
      else
        crc := (crc shl 1);
      dec(i);
    until i<=0;
  end;
  Result := PABYTE(@crc)^;
end;


Uso:
Código Delphi [-]
var
  S: String;
  CRC: ABYTE;
begin
  S:= '13|0000123|1|Maximilian|Mustermann|05051999|21092019';
  CRC:= CCITTx1D0F(PAnsiChar(S), Length(S));
end;


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.
Responder Con Cita
  #13  
Antiguo 05-03-2020
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos,

¡ecfisa! A ver si lo que has probado ha sido el código de scafandra...

¡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...

Código Delphi [-]
var
  S: String;
  CRC: ABYTE;
  Result: string;
begin
  S:= '13|0000123|1|Maximilian|Mustermann|05051999|21092019';
  CRC := CCITTx1D0F(PAnsiChar(S), Length(S));

  Result := IntToHex(CRC[0], 0) + IntToHex(CRC[1], 0);

  // En efecto, se muestra 5320
  ShowMessage(Result);
end;

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.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 06-03-2020 a las 10:58:52.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Ayuda para Convertir Todo este código en Function MaxiDucoli Internet 3 01-10-2017 22:29:07
Convertir cadena aleatoria en cadena de N caracteres DANY OOP 3 12-03-2009 20:49:21
Problemas para validar entrada de datos en delphi 7 Nelly Varios 1 27-03-2007 23:31:25
Tengo un lio con cierto código David OOP 11 13-10-2006 20:07:34
Concatenar Cadena Larga dentro de codigo Delphi JoanKa Conexión con bases de datos 6 04-03-2005 17:53:44


La franja horaria es GMT +2. Ahora son las 22:57:02.


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
Copyright 1996-2007 Club Delphi