Codage en base64 de chaînes unicode

Soyez le premier à donner votre avis sur cette source.

Snippet vu 3 454 fois - Téléchargée 16 fois

Contenu du snippet

Je cherchais depuis un certain temps comment faire pour coder des chaînes Unicode en base64 mais ne trouvant pas de code sur le Net j'ai décider de le faire moi même à partir de zéro. Les seuls codes trouvé sur le Net sont soit pour coder des chaînes ASCII (ANSI) soit pour coder des bytes en ASCII (ANSI)

Source / Exemple :


unit untComBase64;

// Version Unicode by gta126

interface

uses SysUtils;

function encode64(s: string): string;
function decode64(s: string): string;

implementation

const
  tabChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

function encode64(s: string): string;
var
  i       : Integer; // compteur
  charCode: Integer; // code du caractère dans la table Unicode
  valToDec: Integer; // valeur à décrémenter au fur à mesure de la conversion
  nbrBits : Integer; // nombre de bits actuellement dans vaToDec (maximum 16 + 4)
  charPos : Integer; // position dans le tableau de codage en base64
begin
  Result   := '';
  charCode := 0;
  nbrBits  := 0;
  valToDec := 0;

  //parcours des caractères
  for i := 1 to Length(s) do
  begin
    charCode := Ord(s[i]);
    nbrBits  := nbrBits + 16;
    valToDec := (valToDec shl 16) + charCode;

    // traiter les bits tant que l'on sais faire des groupements de 6
    while (nbrBits - 6) >= 0 do
    begin
      nbrBits  := nbrBits - 6;
      charPos  := valToDec shr nbrBits;
      valToDec := valToDec - (charPos shl nbrBits);
      Result   := Result + tabChar[charPos + 1];
    end;
  end;

  // gestion des desniers bits + ajout des compléments
  if nbrBits > 0 then
  begin
    charPos := valToDec shl (6 - nbrBits);
    Result  := Result + tabChar[charPos + 1];

    for i := 1 to (6 - nbrBits) div 2 do
      Result := Result + '=';
  end;
end;

function decode64(s: string): string;
var
  i       : Integer; // compteur
  charPos : Integer; // position dans le tableau de codage en base64
  valToDec: Integer; // valeur à décrémenter au fur à mesure de la conversion
  nbrBits : Integer; // nombre de bits actuellement dans vaToDec (maximum 14 + 6)
  charCode: Integer; // code du caractère dans la table Unicode
  quitLoop: Boolean; // quitter la boucle oui / non
begin
  Result   := '';
  nbrBits  := 0;
  valToDec := 0;
  quitLoop := False;

  // parcours des caractères
  for i := 1 to Length(s) do
  begin
    charPos  := Pos(s[i], tabChar) - 1;
    nbrBits  := nbrBits + 6;
    valToDec := (valToDec shl 6) + charPos;

    // cas des derniers bits trop long ( signe = )
    if (i + 1 <= Length(s)) and (s[i+1] = '=') then
    begin
      valToDec := valToDec shr 2;
      nbrBits := nbrBits - 2;

      if (i + 2 <= Length(s)) and (s[i+2] = '=') then
      begin
        valToDec := valToDec shr 2;
        nbrBits := nbrBits - 2;
      end;

      quitLoop := True;
    end;

    // traitement des bits dès qu'un groupe de 16 est possible
    if (nbrBits - 16) >= 0 then
    begin
      nbrBits  := nbrBits - 16;
      charCode := valToDec shr nbrBits;
      valToDec := valToDec - (charCode shl nbrBits);
      Result   := Result + Char(charCode);
    end;

    // quitter la boucle en ignorant les autres caractères ( ignorer les = )
    if quitLoop then
      Break;
  end;

  // vérification
  if nbrBits > 0 then
    Result:= '';
end;

end.

Conclusion :


Pour le détails du fonctionnement du codage en base64, je vous invite à aller sur http://fr.wikipedia.org/wiki/Base64

A voir également

Ajouter un commentaire

Commentaires

cs_cantador
Messages postés
4996
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
27 mars 2018
9 -
Bonjour,
ce qui aurait été bien, c'est d'indiquer
l'intérêt d'une telle codification, du moins celle que tu aurais notée.
gta126
Messages postés
19
Date d'inscription
dimanche 9 juillet 2006
Statut
Membre
Dernière intervention
29 mars 2011
-
L'intéret de coder en base64 est dans mon cas de pouvoir transmettre des fichiers binaires par réseaux via les composant Indy.

Il y a peut-être une autre façcon de faire pour transmettre des fichiers binaires en réseaux mais je vous explique comment j'ai fait:

1. Par exemple le client demande au serveur un fichier
2. Le serveur ouvre le fichier dans un TFileStream
3. Le serveur lit par exemple les 1024 premiers octets (moins si le fichier est plus petit) et les stockes dans un string (WideString étant sous Delphi XE2)
4. Le serveur code cette string en base64 car la fonction WriteLn des composants Indy pose problème avec des caractères non imprimable (qui sont en grand nombres dans les fichiers binaires).
5. Le serveur envoie les données codées en base64 au client
6. Le client décode les données lues
7. Le client écrit dans un fichier les données reçues
8. Le client demande la suite

etc jusqu'à tout recevoir.

Si d'ailleur il existe une meilleur façcon de transmettre des fichiers en réseaux, je serais ravis de le savoir.

Ici j'ai gérer le cas que les string sont en Unicode donc les caractères sont sur 2 octets ce qui est bien différent que des AnsiString qui elles sont sur 1 octet.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.