[Java]邮件中的编码QuotedPrintable(QP)/乱码处理

2021-08-27 729点热度 0人点赞 0条评论

在处理邮件的时候,可能会遇到主题或者其他内容是类似=?utf-8?b?44Gv5piG5piO77yI5YWs5Lqk6L2m4oyS54eD54On?=这样的,这是邮件的QP(QuotedPrintable)编码,来看下怎么解码。

实现

以下代码实现了QP(QuotedPrintable)解码,详见decodeQuotedPrintable方法

import javax.mail.internet.MimeUtility;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test3 {

    public static void main(String[] args) throws Exception {
        String subject = null;
        try {
            subject = MimeUtility.decodeText(message.getSubject());
        } catch (Exception e) {
            subject = message.getSubject();
        }
        if (isEncoded(subject))
            subject = parserEncoded(subject);
    }

    private static boolean isEncoded(String str) {
        Pattern p = Pattern.compile("=\\?([^\\?]+)\\?([^\\?]+)\\?(.*)\\?=");
        Matcher m = p.matcher(str);
        return m.find();
    }

    private static String parserEncoded(String rawContent) {
        String subject = rawContent;
        // 类似 =?utf-8?b?44Gv5piG5piO77yI5YWs5Lqk6L2m4oyS54eD54On?=
        Pattern p = Pattern.compile("=\\?([^\\?]+)\\?([^\\?]+)\\?(.*)\\?=");
        Matcher m = p.matcher(rawContent);
        StringBuilder sb = new StringBuilder();
        while (m.find()) {
            String encode = m.group(1).toLowerCase();// utf-8
            String bOrQ = m.group(2).toLowerCase();// b base64 q meams
            String content = m.group(3);
            Charset c = Charset.defaultCharset();
            try {
                c = Charset.forName(encode);
            } catch (Exception ignored) {
            }
            try {
                if ("q".equals(bOrQ)) {// QP编码
                    sb.append(new String(decodeQuotedPrintable(content.getBytes()), c));
                } else {
                    sb.append(Base64Coder.decodeString(content));
                }
            } catch (Exception ignored) {
            }
        }
        if (sb.length() > 0)
            subject = sb.toString();
        return subject;
    }

    /**
     * QP(QuotedPrintable)解码
     */
    public static byte[] decodeQuotedPrintable(byte[] bytes) throws Exception {
        if (bytes == null) {
            return null;
        }
        byte ESCAPE_CHAR = '=';
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        for (int i = 0; i < bytes.length; i++) {
            int b = bytes[i];
            if (b == ESCAPE_CHAR) {
                try {
                    int u = Character.digit((char) bytes[++i], 16);
                    int l = Character.digit((char) bytes[++i], 16);
                    if (u == -1 || l == -1) {
                        throw new Exception("Invalid quoted-printable encoding");
                    }
                    buffer.write((char) ((u << 4) + l));
                } catch (ArrayIndexOutOfBoundsException e) {
                    throw new Exception("Invalid quoted-printable encoding");
                }
            } else {
                buffer.write(b);
            }
        }
        return buffer.toByteArray();
    }


}

 

 

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论