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 :

Fonctions UUEncode et UUDecode


Sujet :

Delphi

  1. #1
    Membre actif Avatar de remixtech
    Profil pro
    Enseignant
    Inscrit en
    Février 2003
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2003
    Messages : 272
    Points : 214
    Points
    214
    Par défaut Fonctions UUEncode et UUDecode
    Bonjour,

    Je dois dans mon projet encoder et decoder des fichiers encoder en UUE...
    J'ai bien essayé de m'inspirer de Indy, mais le code ne fonctionne pas, il est totalement buggé...

    Alors je me suis demandé si je ne pouvais pas la coder moi même (je sais je suis fou)...

    Je vous explique le délire, voici des informations rapide sur UUE http://fr.wikipedia.org/wiki/Uuencode..

    J'aimerai savoir si c'est possible et si vous pouviez m'aider un peu (me donner quelques pistes) pour réussir à travailler sur les bytes ainsi...



    J'aimerai utiliser les Streams pour les fonctions.. A quoi faut il que je fasse attention particulièrement (optimisation de code)...

    Je vous remercie d'avance,
    Rémi


    PS : en gros je voudrais :
    à partir d'un octet (base 10) -> le convertir en (base 2) (de la manière la plus rapide possible) ...
    Jouer avec les bytes obtenues pour récupérer un groupe de 6 bits...
    Et récupérer la valeur décimale de ce groupe de 6 bits...

    Autres questions : j'ai une source qui le fait sur un fichier mais je n'y comprend rien :

    qu'est ce que les fonctions shl et shr concrétement ? (je sais lire l'aide)


    pour décoder cette source utilise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
          procedure GetNextHunk;
          var
            I: Integer;
          begin
            for I := 0 to 3 do
              Chars[I] := Byte(NextCh) - Offset;
            Hunk[0] := Byte((Chars[0] shl 2) + (Chars[1] shr 4));
            Hunk[1] := Byte((Chars[1] shl 4) + (Chars[2] shr 2));
            Hunk[2] := Byte((Chars[2] shl 6) + Chars[3]);
            ByteNum := 0
          end;
    Pour encoder :

    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
      procedure FlushHunk;
      var
        I: Integer;
      begin
        if LineLength = CharsPerLine then
          FlushLine;
        Chars[0] := Byte(Hunk[0] shr 2);
        Chars[1] := Byte((Hunk[0] shl 4) + (Hunk[1] shr 4));
        Chars[2] := Byte((Hunk[1] shl 2) + (Hunk[2] shr 6));
        Chars[3] := Byte(Hunk[2] and SixBitMask);
        for I := 0 to 3 do
        begin
          Line[LineLength] := Char((Chars[I] and SixBitMask) + Offset);
          Inc(LineLength);
        end;
        Inc(BytesInLine, NumBytes);
        NumBytes := 0
      end;
    Sachant que SixBitMask vaut
    SixBitMask = $3F;
    Ca veut dire quoi ça ??

    Merci encore,
    J'espère que vous trouverez le temps de répondre... merci

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Citation Envoyé par remixtech Voir le message
    Bonjour,

    Je dois dans mon projet encoder et decoder des fichiers encoder en UUE...
    J'ai bien essayé de m'inspirer de Indy, mais le code ne fonctionne pas, il est totalement buggé...

    Alors je me suis demandé si je ne pouvais pas la coder moi même (je sais je suis fou)...

    Je vous explique le délire, voici des informations rapide sur UUE http://fr.wikipedia.org/wiki/Uuencode..

    J'aimerai savoir si c'est possible et si vous pouviez m'aider un peu (me donner quelques pistes) pour réussir à travailler sur les bytes ainsi...



    J'aimerai utiliser les Streams pour les fonctions.. A quoi faut il que je fasse attention particulièrement (optimisation de code)...

    Je vous remercie d'avance,
    Rémi


    PS : en gros je voudrais :
    à partir d'un octet (base 10) -> le convertir en (base 2) (de la manière la plus rapide possible) ...
    Jouer avec les bytes obtenues pour récupérer un groupe de 6 bits...
    Et récupérer la valeur décimale de ce groupe de 6 bits...

    Autres questions : j'ai une source qui le fait sur un fichier mais je n'y comprend rien :

    qu'est ce que les fonctions shl et shr concrétement ? (je sais lire l'aide)


    pour décoder cette source utilise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
          procedure GetNextHunk;
          var
            I: Integer;
          begin
            for I := 0 to 3 do
              Chars[I] := Byte(NextCh) - Offset;
            Hunk[0] := Byte((Chars[0] shl 2) + (Chars[1] shr 4));
            Hunk[1] := Byte((Chars[1] shl 4) + (Chars[2] shr 2));
            Hunk[2] := Byte((Chars[2] shl 6) + Chars[3]);
            ByteNum := 0
          end;
    Pour encoder :

    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
      procedure FlushHunk;
      var
        I: Integer;
      begin
        if LineLength = CharsPerLine then
          FlushLine;
        Chars[0] := Byte(Hunk[0] shr 2);
        Chars[1] := Byte((Hunk[0] shl 4) + (Hunk[1] shr 4));
        Chars[2] := Byte((Hunk[1] shl 2) + (Hunk[2] shr 6));
        Chars[3] := Byte(Hunk[2] and SixBitMask);
        for I := 0 to 3 do
        begin
          Line[LineLength] := Char((Chars[I] and SixBitMask) + Offset);
          Inc(LineLength);
        end;
        Inc(BytesInLine, NumBytes);
        NumBytes := 0
      end;
    Sachant que SixBitMask vaut

    Ca veut dire quoi ça ??

    Merci encore,
    J'espère que vous trouverez le temps de répondre... merci
    passer par une forme binaire est une très mauvaise idée...surtout pour un gros fichier

    le code que tu donnes est le bon

    SHL (SHift Left) permet un décalage des bits à gauhe
    SHR (SHift Right) permet un décalage des bits à droite

    SixBitMask =$3F c'est la valeur binaire 00111111 qui permet de masquer les bits de retenu (voir plus bas)

    voici le code commenté de mon SendMail

    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
     
    // code pour inclure un fichier dans le corps du mail en UUCode
    function include(filename:string):string;
     var
      f:file;
      s:string;
      u:string;
      i,x:integer;
      ss:integer;
      c1,c2:byte;
     
    // fonction toute simplement pour transformer un nombre
    // entre 0 et 63 en caractère #96,#33..#95
      function uuchr(b:byte):char;
       begin
        if b=0 then result:=#96 else result:=chr(b+32);
       end;
     
     begin
    // ouverture du fichier
      assignfile(f,filename);
      reset(f,1);
      if ioresult<>0 then begin
       result:='$include "'+filename+'" read error';
       exit;
      end;
    // on commencer par une ligne "begin" qui contient le nom du fichier
      result:=#13#10'begin 600 '+filename+#13#10;
    // les lignes suivantes font 76 caractères de long
      setlength(s,76);
    // tant qu'on est pas à la fin du fichier
      while not eof(f) do begin
     // prendre 45 octets (qui seront encodés sur 75 caractères)
       blockread(f,s[1],45,i);
     // encoder la longueur effective (<45 sur la fin de fichier)
       u:=uuchr(i); // UUCoded line lenght
     // on va ramener l'octet sur 6 bits (2 en moins)
       ss:=2;
     // au départ tout va bien
       c2:=0;
     // pour toute la ligne
       for x:=1 to i do begin
      // prendre un octet
        c1:=ord(s[x]);
      // ajouter l'encodage de c1 diminué de ss bits avec la retenue c2
      // au premier passage, c2=0, ss=2
      // si on a un octet qui vaut 171
      // sous la forme binaire il vaut 10101011
      // avec le shr on supprime les deux bits de droite 101010xx
      // reste 101010 soit 42 en décimal, soit 42+32='J' en uucode
        u:=u+uuchr(c2 or (c1 shr ss));
      // on place dans c2 les bits qu'on a supprimé
      // dans notre exemple :
      //  c1=10101011
      // on décale à gauche de 6-2 = 4 bits : 101010110000
      // on ne garde que les 6 premiers bits (63 = 111111)
      // c'est l'opération binaire AND qui le fait
      //       101010110000 
      // AND 000000111111
      //       xxxxxxx110000 
      // reste 48 décimal
        c2:=(c1 shl (6-ss)) and 63;
      // ss passe alors à 4 ("and 7" c'est pour boucler 2, 4, 6, 0, 2, 4, 6...
        ss:=(ss+2) and 7;
      // quand ss passe à 0, on reprend la boucle d'origine
        if ss=0 then begin
         ss:=2;
        // c2 contenant déjà 6 bits, on l'ajoute au résultat
         u:=u+uuchr(c2);
        // et on efface la retenue
         c2:=0;
        end;
       end;
      // en fin de boucle on ajoute les reste
       if (ss>2) then begin
       // compléter la retenue si besoin est
        u:=u+uuchr(c2)+#96; 
        if ss=4 then u:=u+#96;
       end;
      // le tout se termine par un retour à la ligne
       result:=result+u+#13#10;
      end;
     // marqueur de fin de UUCodage
      result:=result+#96#13#10'end'#13#10;
     end;
    dans le code que tu donnes, ils travaillent sur 3 octets d'un coup, en effet si tu codes 1 octet sur 6 bits + 2 bits de retenu, il faut 3 retenus pour produire un nouvel octet uucodé....donc pour 3 octets de départ tu génères 4 octets uucodés. Sinon le principe est le même
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre actif Avatar de remixtech
    Profil pro
    Enseignant
    Inscrit en
    Février 2003
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2003
    Messages : 272
    Points : 214
    Points
    214
    Par défaut
    Merci beaucoup, je vais me creuser la tête un peu la dessus...
    Si je travaille avec les TStreams, je n'ai rien de particulier à faire de plus ?
    Je lis 45 caractères puis j'encode et ainsi de suite..

    Idem pour le décodage, je lis une ligne, je décode, je lis une ligne je décode ..
    Je vous tiens au courrant et je vous donne mon code à la fin merci



  4. #4
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Citation Envoyé par remixtech Voir le message
    Merci beaucoup, je vais me creuser la tête un peu la dessus...
    Si je travaille avec les TStreams, je n'ai rien de particulier à faire de plus ?
    Si ce n'est de lire 3 octets à la fois et ainsi de suite...

    Merci encore,
    la seule chose à gérer quand tu lis par 3 octets à la fois...c'est que le fichier n'a probablement pas une taille multiple de 3
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Membre actif Avatar de remixtech
    Profil pro
    Enseignant
    Inscrit en
    Février 2003
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2003
    Messages : 272
    Points : 214
    Points
    214
    Par défaut
    Excuse moi quand j'ai ecris cela je n'avais pas encore lu ta source . J'ai modifié Merci

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Citation Envoyé par remixtech Voir le message
    Excuse moi quand j'ai ecris cela je n'avais pas encore lu ta source . J'ai modifié Merci
    oui d'ailleurs je constate que dans mon code le SetLength() ne sert à rien j'ai du vouloir éviter l'allocation dynamique de la chaine à une époque et renoncer par la suite
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Membre actif Avatar de remixtech
    Profil pro
    Enseignant
    Inscrit en
    Février 2003
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2003
    Messages : 272
    Points : 214
    Points
    214
    Par défaut
    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
    const
      decalage = 32;
     
      function uuchr(b: byte): char;
      begin
        if b = 0 then
          result := #96
        else
          result := chr(b + decalage);
      end;
     
    var
      Entree, sortie: tmemorystream;
      buffer: string;
      taille_ligne, i, ss, c2, c1: integer;
      ligne: string;
    begin
      entree := tmemorystream.Create;
      sortie := tmemorystream.create;
     
      // On charge le mémo1
      memo1.Lines.SaveToStream(entree);
      entree.Position := 0;
     
      setlength(buffer, 60); // 60 caractères pour du UUEncode
     
      buffer := 'begin 600 ' + 'nom de fichier.fic' + #13#10; // Ecriture de l'en tête
      sortie.Write(buffer[1], length(buffer));
     
      while entree.Position <> entree.Size do
      begin
     
        Taille_ligne := entree.Read(buffer[1], 45); // récupération du premier caractère
     
        ligne := uuchr(Taille_ligne);
     
        ss := 2;
        c2 := 0;
     
        for I := 1 to taille_ligne do
        begin
          c1 := ord(buffer[i]); 
          ligne := ligne + uuchr(c2 or (c1 shr ss));
          c2 := (c1 shl (6 - ss)) and 63;
          ss := (ss + 2) and 7;
          if ss = 0 then
          begin
            ss := 2;
            ligne := ligne + uuchr(c2);
            c2 := 0;
          end;
        end;
     
        if (ss>2) then begin
        ligne:=ligne+uuchr(c2)+#96;
        if ss=4 then ligne:=ligne+#96;
       end;
     
        buffer := ligne+#13#10;
        sortie.Write(buffer[1],length(buffer));
     
      end;
     
        buffer:=#96#13#10'end'#13#10;
     
        sortie.Write(buffer[1],length(buffer));
     
      // On charge le mémo2
      sortie.Position := 0;
      memo2.Lines.LoadFromStream(sortie);
     
      entree.Free;
      sortie.Free;
    end;

    Voici donc mon code, j'ai néanmoins changer un truc :
    setlength(buffer, 61); et non 75 car les lignes peuvent comporter au maximum 61 caractères en UUencode...

    Enfin je crois merci bien pour votre aide,
    Ensuite je ferai le UUDdEcode...

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Deux petites modifications

    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
    const
      decalage = 32;
     
      function uuchr(b: byte): char;
      begin
        if b = 0 then
          result := #96
        else
          result := chr(b + decalage);
      end;
     
    var
      Entree, sortie: tmemorystream;
      buffer: string;
      taille_ligne, i, ss, c2, c1: integer;
      ligne: string;
    begin
      entree := tmemorystream.Create;
      sortie := tmemorystream.create;
     
      // On charge le mémo1
      memo1.Lines.SaveToStream(entree);
      entree.Position := 0;
     
    //  setlength(buffer, 60); // 60 caractères pour du UUEncode
    // ça ne sert à rien en fait :D
     
      buffer := 'begin 600 ' + 'nom de fichier.fic' + #13#10; // Ecriture de l'en tête
      sortie.Write(buffer[1], length(buffer));
     
    // voir le ATTENTION ci-dessous
     SetLength(buffer,45);
     
      while entree.Position <> entree.Size do
      begin
     
    // ATTENTION !!!
        Taille_ligne := entree.Read(buffer[1], 45); // récupération du premier caractère
     
        ligne := uuchr(Taille_ligne);
     
        ss := 2;
        c2 := 0;
     
        for I := 1 to taille_ligne do
        begin
          c1 := ord(buffer[i]); 
          ligne := ligne + uuchr(c2 or (c1 shr ss));
          c2 := (c1 shl (6 - ss)) and 63;
          ss := (ss + 2) and 7;
          if ss = 0 then
          begin
            ss := 2;
            ligne := ligne + uuchr(c2);
            c2 := 0;
          end;
        end;
     
        if (ss>2) then begin
        ligne:=ligne+uuchr(c2)+#96;
        if ss=4 then ligne:=ligne+#96;
       end;
     
        buffer := ligne+#13#10;
        sortie.Write(buffer[1],length(buffer));
     
      end;
     
        buffer:=#96#13#10'end'#13#10;
     
        sortie.Write(buffer[1],length(buffer));
     
      // On charge le mémo2
      sortie.Position := 0;
      memo2.Lines.LoadFromStream(sortie);
     
      entree.Free;
      sortie.Free;
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #9
    Membre actif Avatar de remixtech
    Profil pro
    Enseignant
    Inscrit en
    Février 2003
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2003
    Messages : 272
    Points : 214
    Points
    214
    Par défaut
    En effet, je vois pas pourquoi je n'y ai pas pensé... merci

    Bon j'ai bossé sur le décodage et je pense que c'est bon voici les deux fonctions je joins le projet pour test etc...

    Encodage UUE :


    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
    procedure TForm1.Button1Click(Sender: TObject);
    const
      decalage = 32;
     
      function uuchr(b: byte): char;
      begin
        if b = 0 then
          result := #96
        else
          result := chr(b + decalage);
      end;
     
    var
      Entree, sortie: tmemorystream;
      buffer: string;
      taille_ligne, i, ss, c2, c1: integer;
      ligne: string;
    begin
      entree := tmemorystream.Create;
      sortie := tmemorystream.create;
     
      // On charge le mémo1
      memo1.Lines.SaveToStream(entree);
      entree.Position := 0;
     
      buffer := 'begin 600 ' + 'nom de fichier.fic' + #13#10; // Ecriture de l'en tête
      sortie.Write(buffer[1], length(buffer));
      SetLength(buffer, 45);
     
      while entree.Position <> entree.Size do
      begin
        Taille_ligne := entree.Read(buffer[1], 45); // récupération du premier caractère
     
        ligne := uuchr(Taille_ligne);
     
        ss := 2;
        c2 := 0;
     
        for I := 1 to taille_ligne do
        begin
          c1 := ord(buffer[i]);
          ligne := ligne + uuchr(c2 or (c1 shr ss));
          c2 := (c1 shl (6 - ss)) and 63;
          ss := (ss + 2) and 7;
          if ss = 0 then
          begin
            ss := 2;
            ligne := ligne + uuchr(c2);
            c2 := 0;
          end;
        end;
     
        if (ss > 2) then
        begin
          ligne := ligne + uuchr(c2) + #96;
          if ss = 4 then
            ligne := ligne + #96;
        end;
     
        buffer := ligne + #13#10;
        sortie.Write(buffer[1], length(buffer));
     
      end;
     
      buffer := #96#13#10'end'#13#10;
     
      sortie.Write(buffer[1], length(buffer));
     
      // On charge le mémo2
      sortie.Position := 0;
      memo2.Lines.LoadFromStream(sortie);
     
      entree.Free;
      sortie.Free;
    end;
    Décodage UUE :

    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
    const
      decalage = 32; // Voir le format Unix to Unix Encode sur Wikipedia (le but est d'obtenir toujours des caractères qui s'écrivent)
     
      function chruu(b: char): byte;
      begin
     
        if b = #96 then
          result := 0 // le ' correspond au caractère 0
        else
          result := ord(b) - decalage; // On cherche la valeur réel
     
      end;
     
    var
      Entree, sortie: tmemorystream; // Outil pour mon utilisation
      buffer: string;
      taille_ligne, i, ss, c2: integer;
      ligne, ligne_dec: string;
      liste: tstringlist;
      ligne_en_cours: integer;
    begin
     
      sortie := tmemorystream.create;
      try
        liste := tstringlist.Create;
        try
          entree := tmemorystream.Create;
          try
            ligne_en_cours := 0; //compteur de ligne
            memo2.Lines.SaveToStream(entree); // On charge le mémo2
            entree.Position := 0;
            liste.LoadFromStream(entree); //On charge la liste
          finally
            entree.Free;
          end;
     
          // On cherche la ligne de départ
          while ligne_en_cours < liste.Count do
          begin
            if leftstr(uppercase(trim(liste.Strings[ligne_en_cours])), 5) = 'BEGIN' then
            begin
              inc(ligne_en_cours);
              break;
            end
            else
              inc(ligne_en_cours);
          end;
     
          while ligne_en_cours < liste.Count do
          begin
            ligne := liste.Strings[ligne_en_cours];
            buffer := uppercase(trim(ligne));
            if buffer = #96 then
              break; // Fin du fichier
            if leftstr(buffer, 3) = 'END' then
              break; // Fin du fichier
     
            if buffer <> '' then
            begin
              c2 := 0; // On garde en mémoire le caractère précédant
              ss := 0;
              ligne_dec := '';
              // Sinon on gère la ligne
              for i := 1 to length(ligne) do
              begin
                if i = 1 then
                  // >Recherche de la taille de la ligne
                  taille_ligne := chruu(ligne[1])
                else
                begin
                  if ss = 0 then
                  begin
                    c2 := chruu(ligne[i]); //dans le cas ou on a ss =0 alors on charge le premier caractère qui nous donne un code sur 6 bytes type xx010100 (20)
                    ss := 2;
                  end
                  else
                  begin
                    // EXEMPLE
                    // c2 =  xx010100 (20)  soit visible dans le code (20+32=52) = '4'
                    // chruu(ligne[i]) = xx101010 (42) soit visible dans le code (42+32=74) = 'J'
     
                    // On décrypte
                    // Suivant les différents cas
                    // CAS 1 ss =2
                    // xx010100 shl 2  + xx101010 shr 4 -> 01010010 (82)
                    // CAS 2 SS = 4
                    // xx010100 shl 4  + xx101010 shr 2 -> 01001010 (74)
                    // CAS 3 SS = 6
                    // xx010100 shl 6  + xx101010 shr 0 -> 00101010 (42)
     
                    ligne_dec := ligne_dec + chr(byte((c2 shl (ss)) + (chruu(ligne[i]) shr (6 - ss)))); // ecriture du caractère decrypté
                    c2 := chruu(ligne[i]); // On charge le acarctère en_cours (qui deviendra le caractère précédant à la prochaine passe)
                    ss := ((ss + 2) and 7); // ON boucle ss =2,4,6,0,2,4,6,0
                  end;
     
                end;
     
              end;
     
              ligne_dec := leftstr(ligne_dec, taille_ligne); // On ne garde que ce qui nous interesse (IMPORTANT sinon on obtient des resultats délirants quand on est plus dans un multiple de 3 (derniere ligne))
              sortie.Write(ligne_dec[1], length(ligne_dec));
            end;
            inc(ligne_en_cours);
          end;
     
          sortie.position := 0;
          memo1.Lines.LoadFromStream(sortie); // On charge
     
        finally
          liste.free;
        end;
     
      finally
        sortie.Free;
      end;
    end;
    Voilou, bonne continuation et merci encore Paul
    Fichiers attachés Fichiers attachés

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 12/02/2013, 01h08
  2. Fonction API
    Par margilb dans le forum C++Builder
    Réponses: 2
    Dernier message: 08/07/2002, 11h11
  3. Implémentation des fonctions mathématiques
    Par mat.M dans le forum Mathématiques
    Réponses: 9
    Dernier message: 17/06/2002, 16h19
  4. fonction printf
    Par ydeleage dans le forum C
    Réponses: 7
    Dernier message: 30/05/2002, 11h24
  5. FOnction api specifiant la position de la souris
    Par florent dans le forum C++Builder
    Réponses: 4
    Dernier message: 15/05/2002, 20h07

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