Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Base32 Implementation (https://www.delphipraxis.net/191675-base32-implementation.html)

hhcm 9. Feb 2017 10:41

Base32 Implementation
 
Hallo zusammen,

ich stehe gerade ein wenig auf dem Schlauch. In einer JAVA Anwendung wird ein Base64 String in einen Base32 String konvertiert und ich komme in Delphi einfach nicht auf das gleiche Ergebnis.

In JAVA wird "DngfhpghKu8=" zu "BZ4B7BUYEEVO6==="
Diverse Online-Tools zeigen mir das gleiche Ergebnis.

In Delphi komme ich mit Diversen im Netz gefundenen Funktionen nicht mal annähernd an das Egebnis.
Die Funktion die dem ganzen nahe kommt ist folgende.

Delphi-Quellcode:
const
  base32chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';

function Base32Encode(source: string): string;
var
  i: integer;
  nr: int64;
begin
  result := '';
  while length(source) > 0 do
  begin
    nr := 0;
    for i := 1 to 5 do
    begin
      nr := (nr shl 8);
      if length(source)>=i then
        nr := nr + byte(source[i]);
    end;
    for i := 7 downto 0 do
      if ((length(source)<2) and (i<6)) or
         ((length(source)<3) and (i<4)) or
         ((length(source)<4) and (i<3)) or
         ((length(source)<5) and (i<1)) then
      result := result + '='
    else
      result := result + base32chars[((nr shr (i*5)) and $1F)+1];
    delete(source, 1, 5);
  end;
end;
Ergebnis hier "BZ4B6PZ7EEVO6===" erwartet habe ich "BZ4B7BUYEEVO6==="

Kann mir da mal jemand auf die Sprünge helfen ?

Klaus01 9. Feb 2017 10:46

AW: Base32 Implementation
 
.. was ist, wenn Du ansiSrings verwendest?
Delphi-Quellcode:
function Base32Encode(source: AnsiString): AnsiString;
.. und hat Delphi nicht ein Base32 Encoding enthalten?

Grüße
Klaus

hhcm 9. Feb 2017 10:48

AW: Base32 Implementation
 
Schon ausprobiert, gleiches Ergebnis.
Base32 in Delphi selbst finde ich leider ebenfalls nicht.

Klaus01 9. Feb 2017 11:13

AW: Base32 Implementation
 
Wenn Du das "DngfhpghKu8="hier codierst/encodest
kommt "IRXGOZTIOBTWQS3VHA6QU===" heraus.
Das bekommt man auch mt Deiner Routine.

Wenn Du base64 nach base32 umkodieren willst, muss dann nicht erst
base64 nach Klartext und dann der Klartext nach base32 gewandelt werden.

Grüße
Klaus

hhcm 9. Feb 2017 11:27

AW: Base32 Implementation
 
Das mache ich ja. (Sorry vergessen zu erwähnen)

In Java

base32encode(base64decode("DngfhpghKu8=")) = "BZ4B7BUYEEVO6==="

In Delphi

base32encode(TIdDecoderMIME.DecodeString("Dngfhpgh Ku8=")) = "BZ4B6PZ7EEVO6==="

Klaus01 9. Feb 2017 11:29

AW: Base32 Implementation
 
... und base64decode("DngfhpghKu8=") zeigt das gleiche Ergebnis wie TIdDecoderMIME.DecodeString("DngfhpghKu8=")?

Grüße
Klaus

Uwe Raabe 9. Feb 2017 11:32

AW: Base32 Implementation
 
Der decodierte Base64 Inhalt ist in der Regel nicht konsistent als String darstellbar. Ich würde das als TBytes decoden und den Base32-Encode auch auf TBytes loslassen.

p80286 9. Feb 2017 11:36

AW: Base32 Implementation
 
Zitat:

Zitat von hhcm (Beitrag 1361148)
Das mache ich ja. (Sorry vergessen zu erwähnen)

In Java

base32encode(base64decode("DngfhpghKu8=")) = "BZ4B7BUYEEVO6==="

In Delphi

base32encode(TIdDecoderMIME.DecodeString("Dngfhpgh Ku8=")) = "BZ4B6PZ7EEVO6==="

da stimmt doch was nicht?
Irgendwas ist mit der Darstellung der beiden Strings nicht in Ordnung?

Gruß
K-H

hhcm 9. Feb 2017 11:42

AW: Base32 Implementation
 
Delphi-Quellcode:
tmp := 'DngfhpghKu8=';
aBytes := TBytes(TIdDECoderMime.DecodeBytes(tmp));

result := Base32Encode(aBytes, Length(aBytes));
// Result = '2DS5GALYRLGAC==='
Kommt noch verwirrenderes Zeug bei raus.

Die Byte Implementation ist

Delphi-Quellcode:
function Base32Encode(const buf; len: integer): string;
var
  i: integer;
  nr: int64;
  arr: array of byte;
begin
  result := '';
  SetLength(arr, len);
  Move(buf, arr[0], len);
  while length(arr) > 0 do
  begin
    nr := 0;
    for i := 1 to 5 do
    begin
      nr := (nr shl 8);
      if length(arr)>=i then
        nr := nr + byte(arr[i-1]);
    end;
    for i := 7 downto 0 do
      if ((length(arr)<2) and (i<6)) or
         ((length(arr)<3) and (i<4)) or
         ((length(arr)<4) and (i<3)) or
         ((length(arr)<5) and (i<1)) then
      result := result + '='
    else
      result := result + base32chars[((nr shr (i*5)) and $1F)+1];
    if length(arr)>5 then
    begin
      move(arr[5], arr[0], length(arr)-5);
      setlength(arr, length(arr)-5);
    end
    else
      setlength(arr, 0);
  end;
end;
Zitat:

... und base64decode("DngfhpghKu8=") zeigt das gleiche Ergebnis wie TIdDecoderMIME.DecodeString("Dngfhpgh Ku8=")?
Wie Uwe schon sagte, das ist nicht vernünftig darstellbar.

Uwe Raabe 9. Feb 2017 11:43

AW: Base32 Implementation
 
Ja, das liegt wohl am Indy-Decoding. So funktioniert es:
Delphi-Quellcode:
uses
  System.SysUtils,
  System.NetEncoding;

const
  base32chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';

function Base32Encode(source: TBytes): string;
var
  i: integer;
  L: Integer;
  nr: int64;
  offset: Integer;
begin
  result := '';
  offset := 0;
  L := length(source);
  while L > 0 do
  begin
    nr := 0;
    for i := 0 to 4 do
    begin
      nr := (nr shl 8);
      if i < L then begin
        nr := nr + source[offset + i];
      end;
    end;
    for i := 7 downto 0 do
      if ((L<2) and (i<6)) or
         ((L<3) and (i<4)) or
         ((L<4) and (i<3)) or
         ((L<5) and (i<1)) then
      result := result + '='
    else
      result := result + base32chars[((nr shr (i*5)) and $1F)+1];
    Inc(Offset, 5);
    Dec(L, Offset);
  end;
end;

procedure Main();
begin
  Assert(Base32Encode(TNetEncoding.Base64.DecodeStringToBytes('DngfhpghKu8='))='BZ4B7BUYEEVO6===');
end;

hoika 9. Feb 2017 11:48

AW: Base32 Implementation
 
Hallo,
oder es liegt hieran?

https://forums.embarcadero.com/threa...hreadID=109726

hhcm 9. Feb 2017 12:09

AW: Base32 Implementation
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1361156)
Ja, das liegt wohl am Indy-Decoding. So funktioniert es:
Delphi-Quellcode:
uses
  System.SysUtils,
  System.NetEncoding;

const
  base32chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';

function Base32Encode(source: TBytes): string;
var
  i: integer;
  L: Integer;
  nr: int64;
  offset: Integer;
begin
  result := '';
  offset := 0;
  L := length(source);
  while L > 0 do
  begin
    nr := 0;
    for i := 0 to 4 do
    begin
      nr := (nr shl 8);
      if i < L then begin
        nr := nr + source[offset + i];
      end;
    end;
    for i := 7 downto 0 do
      if ((L<2) and (i<6)) or
         ((L<3) and (i<4)) or
         ((L<4) and (i<3)) or
         ((L<5) and (i<1)) then
      result := result + '='
    else
      result := result + base32chars[((nr shr (i*5)) and $1F)+1];
    Inc(Offset, 5);
    Dec(L, Offset);
  end;
end;

procedure Main();
begin
  Assert(Base32Encode(TNetEncoding.Base64.DecodeStringToBytes('DngfhpghKu8='))='BZ4B7BUYEEVO6===');
end;

Da muss man erst mal drauf kommen. Danke.
Bei kurzen Base64 Kodierten Strings funktioniert das hervorragend.
Bei größeren irgendwie nicht mehr.

"Ubz6l2+TFt80EWAf6CTr/Xocpgn9UhOhSvlGMqQsML1LxieEE7bWqB5Y6HAwaC0NSA50swr GHxKs/UOGPS1SJA=="

sollte

"KG6PVF3PSMLN6NARMAP6QJHL7V5BZJQJ7VJBHIKK7FDDFJBMG C6UXRRHQQJ3NVVIDZMOQ4BQNAWQ2SAOOSZQVRQ7CKWP2Q4GHUW VEJA="

werden.
Bricht aber ab. Sollte das nicht wie folgt sein?

Delphi-Quellcode:
Dec(L, offset);
// wird zu
Dec(L, 5);

Uwe Raabe 9. Feb 2017 12:40

AW: Base32 Implementation
 
Zitat:

Zitat von hhcm (Beitrag 1361158)
Sollte das nicht wie folgt sein?

Delphi-Quellcode:
Dec(L, offset);
// wird zu
Dec(L, 5);

Stimmt allerdings. Ungenügende Testabdeckung...

hhcm 9. Feb 2017 12:41

AW: Base32 Implementation
 
Super, Danke !!

p80286 9. Feb 2017 16:38

AW: Base32 Implementation
 
Falls Du noch eine "Second Source" benötigst Bei Google suchenSZCodeBaseX
Allerdings mußt du aufpassen, welche Version angeboten wird, alles unter 1.3.5 ist älter.

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz