首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Procmail cyrillic转换

Procmail cyrillic转换
EN

Unix & Linux用户
提问于 2019-08-27 08:14:59
回答 1查看 454关注 0票数 1

我为fetchmail编写了一个脚本,用于从帐户接收邮件,并将消息传输到procmail,以便应用过滤器和保存附件。我对消息的主题使用了过滤器,但是源主题中有cyrillics,所以当fetchmail将消息传递到procmail时,最后的主题以UTF-8加密开始,然后只是胡言乱语。

Procmail脚本如下所示:

代码语言:javascript
复制
:0fHw
*^Content-Type:*text/plain; *charset="?(iso-8859-1|US-ASCII|UNKNOWN-8BIT)"?
| formail -i "Content-Type: text/plain; charset=windows-1251"

:0
*^content-Type:
{
:0c
$HOME/fetchmail/backup

:0f
*^Subject:.*ASVA
| uudeview -i +a +o -p $HOME/fetchmail/attachments -
}

这些脚本在拉丁主题上工作得很好,但是由于西里尔主题,我的过滤器没有看到我所放的关键字。如何将主题转换成正确的cyrillics和latinics?我安装了语言包,局部变量设置为ru_RU:UTF-8,当我用cyrillics编写时,它会被正确地显示出来。

EN

回答 1

Unix & Linux用户

发布于 2019-08-27 13:05:51

看来你说的是RFC 2047:电子邮件头的MIME编码。此后,RFCs对RFC进行了扩展,以允许更多的字符集,并可选择地包括语言规范。

由于最初的电子邮件和MIME规范包含了这样的假设,即头将只包含严格的US-ASCII,因此头编码与消息体的MIME编码完全不同。

格式如下:

代码语言:javascript
复制
=?  [*language] ?  ?  ?=

要么是Q表示引用-打印,要么是B表示base64编码.如果这条信息看起来完全是胡言乱语,我想你是在看base64。字符集名称和编码字母都不区分大小写.

所以你可能会看到:

代码语言:javascript
复制
Subject: =?utf-8?b?SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSB1bmRlcnN0b29kIHRoZSBleGFtcGxlLgo=?=

或者添加一个语言ID:

代码语言:javascript
复制
Subject: =?utf-8*en?b?SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSB1bmRlcnN0b29kIHRoZSBleGFtcGxlLgo=?=

手动解码示例:

代码语言:javascript
复制
$ echo "SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSB1bmRlcnN0b29kIHRoZSBleGFtcGxlLgo=" | base64 -d
If you can read this, you understood the example.

现有的Procmail脚本包括强制将字符集编码标记为iso-8859-1US-ASCIIUNKNOWN-8BITwindows-1251,这表明您的实际问题可能是字符编码的标签错误。换言之:

  • 一个旧的电子邮件客户端会发出windows-1251 cyrillics,而不会将它们标记为cyrillics,可能还会出现在标头中。
  • 在途中,电子邮件通过邮件服务器,该服务器要么没有正确地宣布它可以干净地处理8位邮件编码,要么热衷于强制所有字符集的标签,而不是普通的US-ASCII。

在这种情况下,MTA需要对8位字符进行编码和标记,才能传递邮件。但是,如果8位字符没有标签,则只有原始邮件客户端确切地知道字符集实际上是什么。

事实之后标注字符集的问题是,识别字符集可能需要人类级别的理解,以了解内容是否具有解释为特定字符集的意义。因此,您将最终使用启发式,这有时是错误的。

例如,如果您收到的电子邮件实际上是正确编码的iso-8859-1,您的脚本将错误标签为windows-1251,导致任何北欧/西欧重音字符显示为随机的,无意义的Cyrillics。但是,如果这比接收被错误标记为windows-1251iso-8859-1编码的消息更少见,那么您可能会选择接受这种风险,这是很好的。

我认为您必须调查您的有问题的消息,以了解它们的Subject:头实际上是如何编码的。他们是否:

  • 普通的未标记的windows-1251
  • 有效的base64-encoded UTF-8?
  • 还是被base64-encoded误标为UTF-8的-encoded?

不幸的是,procmail及其配套的formail可能不足以以未编码的形式获取Subject:头。他们是自2001年以来未得到维护就连他们的作者现在也建议继续做其他的事情。但是,如果您现在想继续使用procmail,那么您需要这样的脚本:

https://github.com/akkana/scripts/blob/master/decodemail.py

我已经大约10年没有做过重要的procmail脚本了,所以下面的例子可能是错误的,或者有更好的方法来做到这一点。但也许这对解释如何解决这个问题是有用的.

您必须首先解码Subject:头的内容,并将其存储到一个变量中:

代码语言:javascript
复制
:0 h
SUBJDECODED=| decodemail.py Subject:

:0 h
SUBJWASRAW=| formail -xSubject: | recode windows-1251..UTF-8

为了纠正标记错误的编码,您可能需要将字符集从实际的任何内容重新编码到系统使用的UTF-8:

代码语言:javascript
复制
SUBJWASWIN1251=`echo "$SUBJDECODED" | recode windows-1251..UTF-8`

如果有多个可能的编码,您可能需要创建这样的多个变量。

然后,您可以根据主题的任意版本进行匹配:

代码语言:javascript
复制
:0
* SUBJWASRAW ?? your-subject-regexp-here
{
    # Here the subject was raw windows-1251 without any encoding at all.
    # The variable has it converted to valid UTF-8 used by this system,
    # so now the header can be rewritten in an useful form.
    # (This example leaves the subject as raw unlabelled UTF-8 which 
    # may or may not be acceptable to whatever you use to view your email with.
    # But on modern RFC 6532 compliant mail clients 
    # in a system that uses UTF-8 throughout it may actually be OK.)

    :0 f
    | formail -i "Subject: $SUBJWASRAW"
}

:0
* SUBJWASWIN1251 ?? your-subject-regexp-here
{
    # regexp matched, so we know the subject was windows-1251 
    # mislabeled as UTF-8. Fix it.
    :0 f
    | formail -i "Subject: $SUBJWASWIN1251"
}

:0
* SUBJDECODED ?? your-subject-regexp-here
{
    # regexp matched to subject decoded according to existing label
    # so we know that it was validly labelled. But it still needs to
    # be rewritten as it may have been something other than UTF-8.
    :0 f
    | formail -i "Subject: $SUBJDECODED"
}

# Any further rules should be able to match on the subject as usual.

注意:your-subject-regexp-here正则表达式不应该包含^Subject:.*前缀,因为变量将只包含Subject:头的值。

票数 2
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/537606

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档