IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Problème conversion du Code C# vers Delphi7


Sujet :

Delphi

  1. #1
    Membre du Club

    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2008
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 33
    Points : 41
    Points
    41
    Par défaut Problème conversion du Code C# vers Delphi7
    Bonsoir,

    Comme le titre l'indique je suis en train de traduire un code du C# vers Delphi 7, voici ce que dont je suis arrivé à faire si quelqu'un peut me corriger merci.

    C# :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
     
     
    public class CryptoBlock
        {
            private readonly int[] _keytable;
            private int _state;
            private int _counter;
            private int _sum;
     
            public CryptoBlock()
            {
                _keytable = new int[256];
                _state = 0;
                _counter = 0;
                _sum = 0;
            }
     
            public void cc_crypt_init(byte[] key, int len)
            {
                int i;
                for (i = 0; i < 256; i++) _keytable[i] = i;
                int j = 0;
                for (i = 0; i < 256; i++)
                {
                    j = 0xff & (j + key[i % len] + _keytable[i]);
                    // Swap
                    int k = _keytable[i];
                    _keytable[i] = _keytable[j];
                    _keytable[j] = k;
                }
     
                _state = key[0];
                _counter = 0;
                _sum = 0;
            }
     
            public static void cc_crypt_xor(byte[] data)
            {
                string cccam = "CCcam";
                for (sbyte i = 0; i < 8; i++)
                {
                    data[8 + i] = (byte)(i * data[i]);
                    if (i < 5) data[i] ^= (byte)cccam[i];
                }
            }
     
            public void cc_encrypt(byte[] data, int len)
            {
                for (int i = 0; i < len; i++)
                {
                    _counter = 0xff & (_counter + 1);
                    _sum += _keytable[_counter];
     
                    sbyte k = (sbyte)_keytable[_counter];
                    _keytable[_counter] = _keytable[_sum & 0xFF];
                    _keytable[_sum & 0xFF] = k;
     
                    sbyte z = (sbyte)data[i];
                    data[i] = (byte)(z ^ _keytable[_keytable[_counter & 0xFF] + _keytable[_sum & 0xFF] & 0xFF] ^ _state);
                    _state = 0xff & (_state ^ z);
                }
            }
     
            public void cc_decrypt(byte[] data, int len)
            {
                for (int i = 0; i < len; i++)
                {
                    _counter = 0xff & (_counter + 1);
                    _sum += _keytable[_counter];
     
                    sbyte k = (sbyte)_keytable[_counter];
                    _keytable[_counter] = _keytable[_sum & 0xFF];
                    _keytable[_sum & 0xFF] = k;
     
                    sbyte z = (sbyte)data[i];
                    data[i] = (byte)(z ^ _keytable[_keytable[_counter] + _keytable[_sum & 0xFF] & 0xFF] ^ _state);
                    z = (sbyte)data[i];
                    _state = 0xff & (_state ^ z);
                }
            }
        }
    }
     
      private static bool CheckConnectionChecksum(byte[] buf, int len)
            {
                if (len == 16)
                {
                    byte sum1 = (byte)(buf[0] + buf[4] + buf[8]);
                    byte sum2 = (byte)(buf[1] + buf[5] + buf[9]);
                    byte sum3 = (byte)(buf[2] + buf[6] + buf[10]);
                    byte sum4 = (byte)(buf[3] + buf[7] + buf[11]);
     
                    var valid = (sum1 == buf[12]) && (sum2 == buf[13]) && (sum3 == buf[14]) && (sum4 == buf[15]);
                    return valid;
                }
                return false;
            }
     
     
    public static int SendMessage(MsgTypes cmd, int len, byte[] data)
            {
                byte[] sendData;
                if (cmd == MsgTypes.MsgNoHeader)
                {
                    sendData = new byte[len];
                    Array.Copy(data, sendData, len);
                }
                else
                {
                    // build command message
                    sendData = new byte[4 + len];
                    sendData[0] = 0;   // flags??
                    sendData[1] = (byte)((int)cmd & 0xff);
                    sendData[2] = (byte)(len >> 8);
                    sendData[3] = (byte)(len & 0xff);
                    if (len > 0)
                    {
                        Array.Copy(data, 0, sendData, 4, len);
                    }
                }
     
                SendBlock.cc_encrypt(sendData, len);
     
                try
                {
                    return Socket.Send(sendData);
                }
                catch (Exception)
                {
                    Console.WriteLine("Connection closed while sending");
                    Socket.Close();
                }
     
                return -1;
            }

    Delphi 7 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
     
     
     
     
    type  MsgTypes =
        (
            MsgCliInfo = 0,
            MsgEcmCw = 1,
            MsgEmmAck = 2,
            MsgCardDel = 4,
            MsgCmd05 = 5,
            MsgKeepalive = 6,
            MsgCardAdd = 7,
            MsgSrvInfo = 8,
            MsgCmd_0A = 10,
            MsgCmd_0B = 11,
            MsgCmd_0C = 12,
            MsgCmd_0D = 13,
            MsgCmd_0E = 14,
            MsgNewCardSidinfo = 15,
            MsgEcmNok1 = 254,
            MsgEcmNok2 = 255,
            MsgSleepsend = 128,
            MsgCachePush = 129,
            MsgNoHeader = 65535
        );
    var
     FixedData,CustomData:array of Byte;
     CommandTag: MsgTypes;
     DataLength:Integer;
     
    var
     _keytable:array[0..255] of Byte;
     _counter,_sum,_state: byte;
     
    procedure cc_crypt_init(key:array of Byte; len : integer);
    var
      i, j, k : integer;
    begin
      for i := 0 to 255 do _keytable[i] := i;
      j := 0;
      for i := 0 to 255 do
      begin                     //%
        j := $ff and (j + key[i mod len] + _keytable[i]);
        k := _keytable[i];
        _keytable[i] := _keytable[j];
        _keytable[j] := k;
      end;
      _state := key[0];
      _counter := 0;
      _sum := 0;
    end;
     
    procedure cc_encrypt(var Data:array of Byte; len : integer);
    var
      i : integer;
      k, z: byte;
      _Data:array of Byte;
    begin
      SetLength(_Data, len);
      for i := 0 to len-1 do
      begin
        _counter := $ff and (_counter + 1);
        _sum  := _sum + (_keytable[_counter]);
        k := _keytable[_counter];
        _keytable[_counter] := _keytable[_sum and $FF];
        _keytable[_sum and $FF] := k;
        z := data[i];
        _data[i] := (z  xor  _keytable[_keytable[_counter and $FF] + _keytable[_sum and $FF] and $FF]  xor  _state);
        _state := $ff and (_state  xor  z);
      end;
      FillChar(Data, len, #0);
      Move(_data[0], Data[0], len);
    end;
     
    procedure cc_decrypt(var Data:Array of Byte; len : integer);
    var
      i : integer;
      k, z : byte;
      _Data:array of Byte;
    begin
      setlength(_Data, len);
      for i := 0 to len-1 do
      begin
        _counter := $ff and (_counter + 1);
        _sum  := _sum + (_keytable[_counter]);
        k := _keytable[_counter];
        _keytable[_counter] := _keytable[_sum and $FF];
        _keytable[_sum and $FF] := k;
        z := data[i];
        _data[i] := (z  xor  _keytable[_keytable[_counter] + _keytable[_sum and $FF] and $FF]  xor  _state);
        z := data[i];
        _state := $ff and (_state  xor  z);
      end;
      FillChar(Data, len, #0);
      Move(_data, Data, len);
    end;
     
    procedure cc_crypt_xor(var data:array of Byte);
    var
      i:Integer;
      _data:array of Byte;
    begin
      setlength(_data, 16);
      for i := 0 to 8 do
      begin
        _data[8 + i] := Byte(i * data[i]);
        if i < 5 then _data[i] := data[i] xor Byte(cccam[i]);
      end;
      Move(_data, data, 8);
    end;
     
    function CheckConnectionChecksum(wszbuf:Array of Byte; dwlen:Integer):Boolean;
    var
      sum1,sum2,sum3,sum4:Byte;
    begin
      Result := False;
      if (dwlen = 16) then
      begin
        sum1 := (wszbuf[0] + wszbuf[4] + wszbuf[8]);
        sum2 := (wszbuf[1] + wszbuf[5] + wszbuf[9]);
        sum3 := (wszbuf[2] + wszbuf[6] + wszbuf[10]);
        sum4 := (wszbuf[3] + wszbuf[7] + wszbuf[11]);
        Result := (sum1 = wszbuf[12]) and (sum2 = wszbuf[13]) and (sum3 = wszbuf[14]) and (sum4 = wszbuf[15]);
       end
      else Result := False;
    end;
     
     
    function BuildPaCkets(dwSocket:TSocket; wMsg:Byte; var Data; dataLen:Integer):Boolean;
    var
      Header:Array of Byte;
      HeaderLen : Integer;
    begin 
      if wMsg = Byte(MsgTypes(MsgNoHeader)) then
      begin
        SetLength(Header, dataLen);
        HeaderLen := DataLen;
        Move(Data, Header[0], HeaderLen);
      end
     else
      begin
        SetLength(Header, 4 + dataLen);
        HeaderLen := 4 + DataLen;
        Header[0] := 0;   // flags??
        Header[1] := (wMsg and $ff);
        Header[2] := (Datalen shr 8);
        Header[3] := (Datalen and $ff);
        Move(Data, Header[4], DataLen);
      end;
      cc_encrypt(Header[0], HeaderLen);
      Result := (send(dwSocket, Header[0], HeaderLen, 0) <> 0);
      if Result then SetLength(Header, 0);
    end;

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Pourquoi ne pas avoir fait une classe ?
    Déjà tous membres privés seraient initialisés à zéro, cela peut avoir un intérêt d'ailleurs c'est ce que fais le constructeur CryptoBlock()

    cc_decrypt ou cc_crypt_xor, pk avoir utilisé un tableau temporaire ?

    CheckConnectionChecksum, le second Result := False est inutile
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre du Club

    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2008
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 33
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Pourquoi ne pas avoir fait une classe ?
    Déjà tous membres privés seraient initialisés à zéro, cela peut avoir un intérêt d'ailleurs c'est ce que fais le constructeur CryptoBlock()

    cc_decrypt ou cc_crypt_xor, pk avoir utilisé un tableau temporaire ?

    CheckConnectionChecksum, le second Result := False est inutile
    -Pour la CheckConnectionCheksun je suis d’accord avec toi, je l'ai remarqué. Pour la Class c'est un detail, dans mon projet il n'y a aucun intérêt du moment qu'avant d'appeler cc_decrypt ou cc_encrypt on doit toujours passer par cc_init ce qui remet à zéro les variables à la fin.
    et Pour les tableaux temporaires je comprends pas vraiment ce que vous voulez dire ou de quoi tu veux parler. tu veux dire par la déclaration et l'utilisation du _data:Array. ???
    on va l'utiliser comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    procedure cc_crypt_xor(var data:array of Byte);
    var
      i:Integer;
    begin
      for i := 0 to 8 do
      begin
        data[8 + i] := Byte(i * data[i]);
        if i < 5 then data[i] := data[i] xor Byte(cccam[i]);
      end;
    end;
    Ce qui me prends la tête c'est que je n'arrive pas à avoir le résultat, donc je suis un peu perdu car je ne sais pas est-ce que j'ai bien fait la conversion ou bien il y a une erreur quelque part dans le corps de ses fonctions que j'ai posté.

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Déjà c'est < 8 donc 7

    et ce CCcam, je suppose que c'est, en vrai, une valeur d'au moins 8 caractères car [7] ça n'aimera pas

    sbyte et byte, je prendrais soin de les convertir en ShortInt et Byte pour supporter correctement les opérations signées.*

    Je pense que le passage par _data est inutile, le travail sur Data peut-être en direct
    Mais pire, Data un tableau dynamique* donc faut le voir comme un pointeur sur le tableau, j'aurais tendance à écrire Data[0] pour pointer sur la donnée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      FillChar(Data, len, #0);
      Move(_data, Data, len);
    En fait, le FillChar va remplacer l'adresse par des zéros, ton tableau ne pointe plus sur rien, la seconde opération le fait pointer n'importe où et en plus tu écris je ne sais pas où la suite, la mémoire doit bien souffrir

    Pour moi c'est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      ZeroMemory(@Data[0], len);
      Move(_data[0], Data[0], len);
    là c'est bien à l'emplacement du début du tableau que tu écris et non pas dans la référence du tableau


    en Delphi, un tableau dynamique se gère différemment qu'un tableau statique, si le second supporte les opérations que le ferait sur le premier, certain raccourci sur un statique comme la confusion entre Data et Data[0] n'est pas valide sur un tableau dynamique
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 683
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    La déclaration des variables n'est pas bonne et engendre par la suite des problèmes de signe.

    Prenons "k" dans cc_encrypt. il est en sbyte (octet signé) dans le code original mais en byte (octet non signé) dans Delphi. Si _keytable[_counter] = 128, k vaudra 128 en Delphi mais -128 en C. Le calcul d'indice est faussé. En Delphi, ça devrait être un ShortInt.

    Il en va de même pour toutes les déclarations. _keytable est un tableau d'entier en C (peut contenir des valeurs négatives, ce qui sera le cas comme vu précédemment) mais un tableau de byte en Delphi (toujours interprété positif).

    Et à titre informatif : lorsque tu remplis un byte d'une valeur plus grande que 255, seuls les 8 bits de poids faible sont conservés. La plupart des and $FF sont inutiles

    @Shai : non ce n'est pas un tableau dynamique mais un tableau ouvert, la gestion est différente et FillChar(Data, len, #0) est correct (mais inutile du fait du Move sur Len).

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    _data est un tableau dynamique
    Data est un tableau ouvert, oui la subtilité des paramètres, le tableau reçu semble directement pointé sur [0], j'ai toujours pris pour habitude de manipuler ce genre de tableau comme un tableau dynamique mais finalement cela ne semble pas utile d'être parano à ce sujet.

    C'est vicieux du coup _data déclaré en variable locale array of Byte et Data en paramètre var array of Byte, pour comprendre ça
    Move(_data[0], Data, len); - OK
    Move(_data[0], Data[0], len); - OK
    Move(_data, Data, len); - BAD car _data lui est bien dynamique
    Move(_data, Data[0], len); - BAD car _data lui est bien dynamique


    mais bon _data est inutile, ce tampon n'a pas d'intérêt par rapport à l'utilisation directe de Data
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 683
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    le tableau reçu semble directement pointé sur [0]
    C'est ça et c'est pourquoi il n'est pas possible de retailler le tableau malgré la resemblance de la déclaration avec un tableau dynamique et la présence du var (indépendamment de savoir si la source est statique ou dynamique).

    Citation Envoyé par ShaiLeTroll Voir le message
    mais bon _data est inutile, ce tampon n'a pas d'intérêt par rapport à l'utilisation directe de Data
    On est d'accord

  8. #8
    Membre du Club

    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2008
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 33
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    La déclaration des variables n'est pas bonne et engendre par la suite des problèmes de signe.

    Prenons "k" dans cc_encrypt. il est en sbyte (octet signé) dans le code original mais en byte (octet non signé) dans Delphi. Si _keytable[_counter] = 128, k vaudra 128 en Delphi mais -128 en C. Le calcul d'indice est faussé. En Delphi, ça devrait être un ShortInt.

    Il en va de même pour toutes les déclarations. _keytable est un tableau d'entier en C (peut contenir des valeurs négatives, ce qui sera le cas comme vu précédemment) mais un tableau de byte en Delphi (toujours interprété positif).

    Et à titre informatif : lorsque tu remplis un byte d'une valeur plus grande que 255, seuls les 8 bits de poids faible sont conservés. La plupart des and $FF sont inutiles

    @Shai : non ce n'est pas un tableau dynamique mais un tableau ouvert, la gestion est différente et FillChar(Data, len, #0) est correct (mais inutile du fait du Move sur Len).
    Merci, tu es bien clair dans tes réponses, voici ce que j'ai dû changer.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
     
    //-------------------------
    procedure _crypt_init(key : Array of byte; len : integer);
    var
      i, j, k : integer;
    begin
      for i := 0 to 255 do _keytable[i] := i;
      j := 0;
      for i := 0 to 255 do
      begin
        j := (j + key[i mod len] + _keytable[i]);
        k := _keytable[i];
        _keytable[i] := _keytable[j];
        _keytable[j] := k;
      end;
      _state := key[0];
      _counter := 0;
      _sum := 0;
    end;
     
     
    procedure _decrypt(var data : Array of byte; len : integer);
    var
      i : integer;
      z,k : shortint;
    begin
      for i := 0 to len-1 do
      begin
        _counter :=  (_counter + 1);
        _sum  := _sum + (_keytable[_counter]);
        k := _keytable[_counter];
        _keytable[_counter] := _keytable[_sum];
        _keytable[_sum ] := k;
        z := data[i];
        data[i] := (z  xor  _keytable[_keytable[_counter] + _keytable[_sum ] and $FF]  xor  _state);
        z := data[i];
        _state := (_state  xor  z);
      end;
    end;
     
    procedure _encrypt(var data : Array of byte; len : integer);
    var
      i : integer;
      k, z: shortint;
    begin
      for i := 0 to len-1 do
      begin
        _counter := (_counter + 1);
        _sum  := _sum + (_keytable[_counter]);
        k := _keytable[_counter];
        _keytable[_counter] := _keytable[_sum ];
        _keytable[_sum ] := k;
        z := data[i];
        data[i] := (z  xor  _keytable[_keytable[_counter ] + _keytable[_sum ] and $ff]  xor  _state);
        _state := (_state  xor  z);
      end;
    end;
     
    procedure _crypt_xor(var buf : Array of byte; cccam_str:string);
    var
      i : ShortInt;
    begin
      for i := 0 to 7 do
      begin
        buf[i + 8] := i * buf[i];
        if i <= 5 then buf[i] := buf[i] xor Ord(cccam_str[i]);
      end;
    end;

  9. #9
    Membre du Club

    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2008
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 33
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Déjà c'est < 8 donc 7

    et ce CCcam, je suppose que c'est, en vrai, une valeur d'au moins 8 caractères car [7] ça n'aimera pas

    sbyte et byte, je prendrais soin de les convertir en ShortInt et Byte pour supporter correctement les opérations signées.*

    Je pense que le passage par _data est inutile, le travail sur Data peut-être en direct
    Mais pire, Data un tableau dynamique* donc faut le voir comme un pointeur sur le tableau, j'aurais tendance à écrire Data[0] pour pointer sur la donnée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      FillChar(Data, len, #0);
      Move(_data, Data, len);
    En fait, le FillChar va remplacer l'adresse par des zéros, ton tableau ne pointe plus sur rien, la seconde opération le fait pointer n'importe où et en plus tu écris je ne sais pas où la suite, la mémoire doit bien souffrir

    Pour moi c'est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      ZeroMemory(@Data[0], len);
      Move(_data[0], Data[0], len);
    là c'est bien à l'emplacement du début du tableau que tu écris et non pas dans la référence du tableau


    en Delphi, un tableau dynamique se gère différemment qu'un tableau statique, si le second supporte les opérations que le ferait sur le premier, certain raccourci sur un statique comme la confusion entre Data et Data[0] n'est pas valide sur un tableau dynamique
    Ok, !
    * Pour les tableaux je passerais direct sans les utiliser, moi tellement je n'arrivais pas à avoir un résultat j'ai commencé à faire et/ou ajouter des trucs.

  10. #10
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 683
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    Tu as choisi le chemin compliqué. Il suffisait de remettre les types originaux quitte à simplifier le code une fois fonctionnel.

    Tu as certainement encore d'autres problèmes au niveau de la priorité des opérations qui d'après ce que je vois n'est pas la même en C# qu'en Delphi.

    Par exemple dans cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data[i] := (z xor _keytable[_keytable[_counter] + _keytable[_sum] and $FF] xor _state);
    and est prioritaire sur + et ne s'applique qu'à _keytable[_sum], l'indice peut dépasser 255.

    A corriger en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data[i] := z xor _keytable[(_keytable[_counter] + _keytable[_sum]) and $FF] xor _state;
    .

  11. #11
    Membre du Club

    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2008
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 33
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Tu as choisi le chemin compliqué. Il suffisait de remettre les types originaux quitte à simplifier le code une fois fonctionnel.

    Tu as certainement encore d'autres problèmes au niveau de la priorité des opérations qui d'après ce que je vois n'est pas la même en C# qu'en Delphi.

    Par exemple dans cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data[i] := (z xor _keytable[_keytable[_counter] + _keytable[_sum] and $FF] xor _state);
    and est prioritaire sur + et ne s'applique qu'à _keytable[_sum], l'indice peut dépasser 255.

    A corriger en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data[i] := z xor _keytable[(_keytable[_counter] + _keytable[_sum]) and $FF] xor _state;
    .
    Merci pour ta correction et tes explications, tu veux dire quoi par ( choisi le chemin compliqué ...), est ce que je dois aussi convertir les déclarations globales dont :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     _keytable:array[0..255] of Byte;
     _counter,_sum,_state: byte;
    par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     _keytable:array[0..255] of shortint;
     _counter,_sum,_state: shortint;

  12. #12
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            private readonly int[] _keytable;
            private int _state;
            private int _counter;
            private int _sum;
    int du C# c'est Integer en Delphi
    Surement pour cela qu'il y a pas mal de transtypage et les masques 0xFF

    Il semble évident que la première chose à faire c'est de respecter les mêmes types mais aussi de comprendre ce que font les opérations C# pour vérifier si elles font vraiment ce que vous pensez et donc les traduire au mieux.

    Votre dernière remarque de tout passé en shortint est inquiétante car vous semblez faire cela au hasard sans comprendre.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  13. #13
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 683
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    En C#, c'était des int, donc en Delphi des integer. J'aurais conservé ton premier code qui était quasi une représentation 1:1 du code C# mais en définissant également les mêmes types.

    C'est seulement une fois que le tout était fonctionnel que j'aurais commencé à nettoyer et simplifier. Là malheureusement tu ne fais qu'ajouter de nouvelles erreurs. Ex. j dans cc_crypt_init est maintenant faux. Soit c'est un byte, soit un integer and $FF.

    Citation Envoyé par Hs32-Idir Voir le message
    est ce que je dois aussi convertir les déclarations globales dont :
    Ce qui est logique pour _keytable puisque tu as des valeurs signées mais pas du tout pour counter qui est toujours positif entre 0 et 255


    Edit: Shai tape beaucoup plus vite que moi

  14. #14
    Membre du Club

    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2008
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 33
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Votre dernière remarque de tout passé en shortint est inquiétante car vous semblez faire cela au hasard sans comprendre.
    C'est un peu vrai je commence à tout mélanger le fait que je n'arrivais pas à avoir un résultat, bon bref, je remis tout à zéro, j'ai dû reconvertir le tout en utilisant les mêmes équivalents c/Delphi si je peux dire ça, voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
     
    var
     _keytable:array[0..255] of Integer;
     _counter,_sum,_state: Integer;
     
     
    procedure cccam_crypt_init(key : array of Byte; len :  Integer); 
    var
      i : Integer;
      j : Integer;
      k : Integer;
    begin
      j := 0;
      for i := 0 to 255 do _keytable[i] := i;
      for i := 0 to 255 do
      begin
        j := $FF and (j + key[ i mod len] + _keytable[i]);
        k := _keytable[i];
        _keytable[i] := _keytable[j];
        _keytable[j] := k;
      end;
      _state := key[0];
      _counter := 0;
      _sum := 0;
    end;
     
    procedure cccam_decrypt(var data : array of byte; len :  Integer); 
    var
      i : Integer;
      z : ShortInt;
      k : ShortInt;
    begin
      for i := 0 to len-1 do
      begin
        _counter := $FF and (_counter + 1);
        _sum  := _sum + (_keytable[_counter]);
        k := ShortInt(_keytable[_counter]);
        _keytable[_counter] := _keytable[_sum and $FF];
        _keytable[_sum and $FF ] := k;
        z := ShortInt(data[i]);
        data[i] := ShortInt(z  xor _keytable[(_keytable[_counter] + _keytable[_sum and $FF]) and $FF]  xor  _state);
        z := ShortInt(data[ i]);
        _state := $FF and (_state  xor  z);
      end;
    end;
     
    procedure cccam_encrypt(var data : array of Byte; len :  Integer); 
    var
      i : Integer;
      z : ShortInt;
      k : ShortInt;
    begin
      for i := 0 to len-1 do
      begin
        _counter := $FF and (_counter + 1);
        _sum  := _sum + (_keytable[_counter]);
        k := ShortInt(_keytable[_counter]);
        _keytable[_counter] := _keytable[_sum and $FF ];
        _keytable[_sum and $FF ] := k;
        z := ShortInt(data[i]);
        data[i] := ShortInt(z xor _keytable[(_keytable[_counter and $FF] + _keytable[_sum and $FF]) and $FF] xor _state);
        _state := $FF and (_state  xor  z);
      end;
    end;
     
    procedure cccam_crypt_xor(var buf : array of byte; cccam_str:string); 
    var
      i : ShortInt;
    begin
      for i := 0 to 8 do
      begin
        buf[i + 8] := Byte(i * buf[i]);
        if i <= 5 then buf[i-1] := buf[i-1] xor Byte(cccam_str[i]);
      end;
    end;

  15. #15
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 683
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    Merci pour le code mais à toi de dire si tu arrives à chiffrer/déchiffrer

    As-tu remarqué que encrypt/decrypt sont parfaitement identiques ?

    Et ceci Byte(cccam_str[i]) fonctionnera en D7 mais plus sur les Delphi récents, les string sont maintenant unicode. Et accessoirement les chaînes sont à base 1.

  16. #16
    Membre du Club

    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2008
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 33
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Merci pour le code mais à toi de dire si tu arrives à chiffrer/déchiffrer

    As-tu remarqué que encrypt/decrypt sont parfaitement identiques ?

    Et ceci Byte(cccam_str[i]) fonctionnera en D7 mais plus sur les Delphi récents, les string sont maintenant unicode. Et accessoirement les chaînes sont à base 1.
    Merci à vous pour votre aide, moi je suis sur D7, je crois que ça fonctionne, j'ai essayé de crypter un texte sous C et le même sur Delphi je suis arrivé au même résultat, si quelqu'un est intéressé je ferais en sorte de mettre en class et de crie une unité Delphi et la poster pour que les autres profitent aussi, et si quelqu'un peut le modifie pour que ça fonctionne sous les versions récentes sa sera sympa.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Conversion petit code Python vers MATLAB
    Par recherche888 dans le forum MATLAB
    Réponses: 13
    Dernier message: 30/11/2011, 10h34
  2. Conversion de code C# vers Java (unsigned)
    Par kraxdaz dans le forum Général Java
    Réponses: 1
    Dernier message: 12/09/2011, 14h43
  3. Conversion de code ruby vers C#
    Par Abalalojik dans le forum Ruby
    Réponses: 1
    Dernier message: 30/08/2011, 00h13
  4. [Débutant] Problème conversion Cbuilder 6.0 vers C++Builder XE
    Par Godzestla dans le forum C++Builder
    Réponses: 11
    Dernier message: 18/05/2011, 12h28
  5. [VB.net]problème de conversion de code c# vers VB.net
    Par cladsam dans le forum Windows Forms
    Réponses: 2
    Dernier message: 18/10/2005, 14h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo