1

我正在尝试将用希伯来语编写的电子邮件的“主题”字段编码为 Base64,以便可以在所有浏览器中正确阅读主题。目前,我正在使用编码 Windows-1255,它适用于某些客户端但不是全部,所以我想使用 utf-8、base64。

我对这个主题的阅读(没有双关语)表明文本必须是形式

=?<charset>?<encoding>?<encoded text>?=

例如

=?windows-1255?Q?=E0=E1?=

我从使用 UTF-8B 编码的希伯来语发送给我的信件中提取了编码的主题行,并在这个网站 www.webatic.com/run/convert/base64.php 上成功解码了它们。我还使用这个网站对简单字母进行编码,并注意到返回编码与从 Delphi 算法得到的结果不同。

所以 - 我正在寻找一种成功编码字母的算法,例如 aleph (ord=224)、bet (ord=225) 等。根据网站,由两个字母 aleph 和 bet 组成的字符串返回代码 15DXkq= =,但基本的 Delphi 算法返回 Ue4,而 TIdEncoderQuotedPrintable 组件返回 =E0=E1(这是 ISO-8859 编码)。

编辑(经过几条评论):

我让一个朋友从她的 Mac 电脑上给我发一封电子邮件,这并不奇怪,它使用 UTF-8 编码(而不是 Windows-1255)。主题是一个字母,aleph,ord 224。编码的主题出现在电子邮件的标题中,如下所示

=?UTF-8?B?15A=?=

这可以分为三个部分: '前缀' (=?UTF-8?B?),这意味着正在使用带有 base64 编码的 UTF-8;'有效负载'(15A =),我引用的网站将其正确翻译为字母aleph;和后缀 (?=)。

我需要一种算法来将任意字符串翻译,其中大部分将是希伯来语(因此使用 ord >= 224)到 base64/utf-8;正确的解决方案是在引用的网站上正确解码。

4

2 回答 2

1

很抱歉浪费了你所有的时间。今天我又花了几个小时在这个主题上,发现我使用的 base64 代码有一个巨大的错误。

发送 base64 编码的 UTF-8 主题行所需的步骤是:

  1. 通过 AnsiToUTF8 函数将“普通”文本(即本地 ANSI 代码页)转换为 UTF-8
  2. 将此编码为base64
  3. 创建一个前缀为 '=?UTF-8?B?'、第 2 阶段的结果和后缀为 '=?=' 的字符串
  4. 发送!

这是创建和发送电子邮件的完整代码(明显简化)

 with IdSMTP1 do
  begin
   host:= ....;
   username:= ....;
   password:= ....;
  end;

 with email do
  begin
   From.Address:= ....;
   Recipients.EMailAddresses:= ....;
   cclist.add.address:= ....;
   email.subject:= '=?UTF-8?B?' + encode64 (AnsiToUTF8 (edit1.text)) +  '=?=';
   email.Body.text:= ....;
  end;

 try
  IdSMTP1.Connect (1000);
  IdSMTP1.Send (email);
 finally
  if IdSMTP1.Connected
   then IdSMTP1.Disconnect;
 end;

使用此页面上与此页面相同的代码 codes64 ”字符串以数字开头,然后是大写字母,然后是小写字母,然后是标点符号。但是这个页面 显示应该是大写字母,然后是小写字母,然后是数字,然后是标点符号。

一旦我做了这个更正,字符串开始被“正确”编码——我可以在我的电子邮件客户端中正确地阅读它们,我认为这是“正确”的定义。

了解其他人是否对我发现的 base64 编码代码有问题会很有趣。

于 2013-01-13T16:33:40.967 回答
0

您根本不需要Subject手动对属性进行编码。 TIdMessage自动为您编码。只需将 Edit1.Text值原样分配给 the SubjectTIdMessage根据需要对其进行编码。

如果您想自定义如何对 TIdMessage标头进行编码,请使用该TIdMessage.OnInitializeISO 事件来提供所需的字符集和编码值。在 Delphi 2009+ 中,它默认为 UTF-8 和 Base64。在早期版本中,TIdMessage读取 RTL 的当前操作系统语言并为已知语言选择一些默认值。但是,希伯来语不是其中之一,因此最终会使用 ISO-8859-1 和 QuotedPrintable。您可以覆盖这些值,例如:

email.Subject := Edit1.Text;

.

procedure TForm1.emailInitializeISO(var VHeaderEncoding: Char; var VCharSet: string);
begin
  VHeaderEncoding := 'B';
  VCharSet := 'UTF-8';
end;
于 2013-01-18T07:04:41.747 回答