Einzelnen Beitrag anzeigen

flashcoder

Registriert seit: 10. Nov 2013
83 Beiträge
 
#2

AW: Bitcoin Bech32 implementierung

  Alt 28. Jun 2023, 16:08
Hier ist ein von ChatGPT aus F# übersetzter code und eine kleine Änderung:

Delphi-Quellcode:
uses
  Generics.Collections;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
const
  Charset = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
  Generator: array[0..4] of UInt32 = ($3B6A57B2, $26508E6D, $1EA119FA, $3D4233DD, $2A1462B3);
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
function Polymod(const Values: array of UInt32): UInt32;
var
  Chk, B, I, J: UInt32;
begin
  Chk := 1;
  for I := 0 to Length(Values) - 1 do
  begin
    B := Chk shr 25;
    Chk := ((Chk and $1FFFFFF) shl 5) xor Values[I];
    for J := 0 to 4 do
    begin
      if (B shr J) and 1 = 1 then
        Chk := Chk xor Generator[J];
    end;
  end;
  Result := Chk;
end;

function ExpandHrp(const Hrp: string): TList<UInt32>;
var
  I: Integer;
begin
  Result := TList<UInt32>.Create;
  for I := 1 to Length(Hrp) do
    Result.Add(Ord(Hrp[I]) shr 5);
  Result.Add(0);
  for I := 1 to Length(Hrp) do
    Result.Add(Ord(Hrp[I]) and 31);
end;

function VerifyChecksum(const Hrp: string; const Data: TList<UInt32>): Boolean;
var
  HrpExpand: TList<UInt32>;
begin
  HrpExpand := ExpandHrp(Hrp);
  try
    HrpExpand.AddRange(Data.ToArray);
    Result := Polymod(HrpExpand.ToArray) = 1;
  finally
    HrpExpand.Free;
  end;
end;

function IsBech32Address(const Str: string): Boolean;
var
  LastOneIndex: Integer;
  Hrp, Data: string;
  DataValues: TList<UInt32>;
  I, V: Integer;
begin
  LastOneIndex := Pos('1', Str);
  Hrp := Copy(Str, 1, LastOneIndex - 1);
  Data := Copy(Str, LastOneIndex + 1, Length(Str));
  DataValues := TList<UInt32>.Create;
  try
    for I := 1 to Length(Data) do
    begin
      V := Pos(Data[I], Charset);
      if V = 0 then
        raise Exception.Create('invalid bech32 address')
      else
        DataValues.Add(V - 1);
    end;
    if VerifyChecksum(Hrp, DataValues) then
      Result := True
    else
      raise Exception.Create('invalid bech32 address');
  finally
    DataValues.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if IsBech32Address('bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4') then
    ShowMessage('Valid.');
end;

end.

Geändert von flashcoder (28. Jun 2023 um 23:22 Uhr)
  Mit Zitat antworten Zitat