使用 Base64 UTF-8 阿拉伯字符串时的 QR 读取问题
QR reading problem when using a Base64 UTF-8 Arabic string
我有一个标记的阿拉伯字符串,我想使用 Base64 编码对该字符串进行编码。在此字符串中使用英文字母时一切运行完美,但使用阿拉伯字母时,QR reader 未显示正确的字母。
这是我的代码:
function TForm1.GetMyString(TagNo: Integer; TagValue: string): string;
var
Bytes, StrByte: TBytes;
i: Integer;
begin
SetLength(StrByte, Length(TagValue)+2);
StrByte[0] := Byte(TagNo);
StrByte[1] := Byte(Length(TagValue));
for i := 2 to Length(StrByte)-1 do
StrByte[i] := Byte(TagValue[i-1]);
Result := TEncoding.UTF8.GetString(StrByte);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
s: String;
Bytes: TBytes;
begin
s := GetMyString(1, Edit1.Text) + GetMyString(2, Edit2.Text) +
GetMyString(3, Edit3.Text) + GetMyString(4, Edit4.Text) +
GetMyString(5, Edit5.Text);
bytes := TEncoding.UTF8.GetBytes(s);
QREdit.Text := TNetEncoding.Base64.EncodeBytesToString(Bytes);
end;
解码Base64字符串后,同样显示二维码读取结果
例如。 (E) 'D9E1'F)
而不是 (مؤسسة العمران)
我正在使用 ZXingQR 读取生成的字符串。
GetMyString()
是 截断 一系列 UTF-16 字符到一个 8 位字节的数组中,以及将其他 非文本 字节到数组中,然后将整个数组视为 UTF-8(实际上不是)以生成新的 UTF-16 字符串。
然后 Button1Click()
正在获取那些顶起的 UTF-16 字符串,将它们连接在一起,并将结果转换为 UTF-8 以编码为 base64。
此方法仅适用于长度小于 128 个字符的 ASCII 字符串,以及值小于 128 的标记,因为 0..127 范围内的 ASCII 字节是 UTF-8 的子集。这不适用于超出此范围的非 ASCII characters/bytes。
您似乎想对一系列带标签的UTF-8 字符串进行base64 编码。如果是这样,那么尝试更像这样的东西:
procedure TForm1.GetMyString(TagNo: UInt8; const TagValue: string; Output: TStream);
var
Bytes: TBytes;
begin
Bytes := TEncoding.UTF8.GetBytes(TagValue);
Assert(Length(Bytes) < 256);
Output.WriteData(TagNo);
Output.WriteData(UInt8(Length(Bytes)));
Output.WriteData(Bytes, Length(Bytes));
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
try
GetMyString(1, Edit1.Text, Stream);
GetMyString(2, Edit2.Text, Stream);
GetMyString(3, Edit3.Text, Stream);
GetMyString(4, Edit4.Text, Stream);
GetMyString(5, Edit5.Text, Stream);
QREdit.Text := TNetEncoding.Base64.EncodeBytesToString(Stream.Memory, Stream.Size);
finally
Stream.Free;
end;
end;
或者:
function TForm1.GetMyString(TagNo: UInt8; const TagValue: string): TBytes;
var
Len: Integer;
begin
Len := TEncoding.UTF8.GetByteCount(TagValue);
Assert(Len < 256);
SetLength(Result, 2+Len);
Result[0] := Byte(TagNo);
Result[1] := Byte(Len);
TEncoding.UTF8.GetBytes(TagValue, 1, Length(TagValue), Result, 2);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Bytes: TBytes;
begin
Bytes := Concat(
GetMyString(1, Edit1.Text),
GetMyString(2, Edit2.Text),
GetMyString(3, Edit3.Text),
GetMyString(4, Edit4.Text),
GetMyString(5, Edit5.Text)
);
QREdit.Text := TNetEncoding.Base64.EncodeBytesToString(Bytes);
end;
我有一个标记的阿拉伯字符串,我想使用 Base64 编码对该字符串进行编码。在此字符串中使用英文字母时一切运行完美,但使用阿拉伯字母时,QR reader 未显示正确的字母。
这是我的代码:
function TForm1.GetMyString(TagNo: Integer; TagValue: string): string;
var
Bytes, StrByte: TBytes;
i: Integer;
begin
SetLength(StrByte, Length(TagValue)+2);
StrByte[0] := Byte(TagNo);
StrByte[1] := Byte(Length(TagValue));
for i := 2 to Length(StrByte)-1 do
StrByte[i] := Byte(TagValue[i-1]);
Result := TEncoding.UTF8.GetString(StrByte);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
s: String;
Bytes: TBytes;
begin
s := GetMyString(1, Edit1.Text) + GetMyString(2, Edit2.Text) +
GetMyString(3, Edit3.Text) + GetMyString(4, Edit4.Text) +
GetMyString(5, Edit5.Text);
bytes := TEncoding.UTF8.GetBytes(s);
QREdit.Text := TNetEncoding.Base64.EncodeBytesToString(Bytes);
end;
解码Base64字符串后,同样显示二维码读取结果
例如。 (E) 'D9E1'F)
而不是 (مؤسسة العمران)
我正在使用 ZXingQR 读取生成的字符串。
GetMyString()
是 截断 一系列 UTF-16 字符到一个 8 位字节的数组中,以及将其他 非文本 字节到数组中,然后将整个数组视为 UTF-8(实际上不是)以生成新的 UTF-16 字符串。
然后 Button1Click()
正在获取那些顶起的 UTF-16 字符串,将它们连接在一起,并将结果转换为 UTF-8 以编码为 base64。
此方法仅适用于长度小于 128 个字符的 ASCII 字符串,以及值小于 128 的标记,因为 0..127 范围内的 ASCII 字节是 UTF-8 的子集。这不适用于超出此范围的非 ASCII characters/bytes。
您似乎想对一系列带标签的UTF-8 字符串进行base64 编码。如果是这样,那么尝试更像这样的东西:
procedure TForm1.GetMyString(TagNo: UInt8; const TagValue: string; Output: TStream);
var
Bytes: TBytes;
begin
Bytes := TEncoding.UTF8.GetBytes(TagValue);
Assert(Length(Bytes) < 256);
Output.WriteData(TagNo);
Output.WriteData(UInt8(Length(Bytes)));
Output.WriteData(Bytes, Length(Bytes));
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
try
GetMyString(1, Edit1.Text, Stream);
GetMyString(2, Edit2.Text, Stream);
GetMyString(3, Edit3.Text, Stream);
GetMyString(4, Edit4.Text, Stream);
GetMyString(5, Edit5.Text, Stream);
QREdit.Text := TNetEncoding.Base64.EncodeBytesToString(Stream.Memory, Stream.Size);
finally
Stream.Free;
end;
end;
或者:
function TForm1.GetMyString(TagNo: UInt8; const TagValue: string): TBytes;
var
Len: Integer;
begin
Len := TEncoding.UTF8.GetByteCount(TagValue);
Assert(Len < 256);
SetLength(Result, 2+Len);
Result[0] := Byte(TagNo);
Result[1] := Byte(Len);
TEncoding.UTF8.GetBytes(TagValue, 1, Length(TagValue), Result, 2);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Bytes: TBytes;
begin
Bytes := Concat(
GetMyString(1, Edit1.Text),
GetMyString(2, Edit2.Text),
GetMyString(3, Edit3.Text),
GetMyString(4, Edit4.Text),
GetMyString(5, Edit5.Text)
);
QREdit.Text := TNetEncoding.Base64.EncodeBytesToString(Bytes);
end;