使用8位字节的编码格式将字节流安全的转换成String

我们常用的编码格式有ASCII,Unicode,UTF-8,GB2312等,如何在这些编码之间安全转换呢?

最近做邮件系统,采用了OpenPOP组件,这是老外写的,没想到用到中文环境中,出了很多问题,主要就是编码问题。

通常,邮件内容都会经过Base64编码,在邮件接收端,需要对其解码,得到字节流,再进一步解码为正确的字符串,如 Base64.cs文件中:

public static class Base64
    {
        public  static byte[] DecodeToBytes(string strText)
        {
            try
            {
                return Convert.FromBase64String(strText);
            }
            catch (Exception e)
            {
                Utility.LogError("decodeToBytes:" + e.Message);
                
                return Encoding.Default.GetBytes("\0");
            }
        }
        /// <summary>
        /// Decoded a Base64 encoded string using the Default encoding of the system
        /// </summary>
        /// <param name="base64Encoded">Source string to decode</param>
        /// <returns>A decoded string</returns>
        public static string Decode(string base64Encoded)
        {
            //有可能因为二进制问题不能正确解码 dth,2010.12.15
            //return Encoding.Default.GetString(DecodeToBytes(base64Encoded));
            //ISO8859-1 字符串,8位,只有这种可以完整保留二进制
            Encoding _encoding = Encoding.GetEncoding(28591);
            return _encoding.GetString(DecodeToBytes(base64Encoded));
        }
        /// <summary>
        /// Decoded a Base64 encoded string using a specified encoding
        /// </summary>
        /// <param name="base64Encoded">Source string to decode</param>
        /// <param name="nameOfEncoding">The name of the encoding to use</param>
        /// <returns>A decoded string</returns>
        public static string Decode(string base64Encoded, string nameOfEncoding)
        {
            try
            {
                return Encoding.GetEncoding(nameOfEncoding).GetString(DecodeToBytes(base64Encoded));
            }
            catch(Exception e)
            {
                Utility.LogError("decode: " + e.Message);
                return Decode(base64Encoded);
            }
        }
    }

其中有一个方法Decode,这是原来的代码:

public static string Decode(string base64Encoded)
        {
  return Encoding.Default.GetString(DecodeToBytes(base64Encoded));
 }

原作者使用了 Encoding.Default 编码格式来获取字符串,在英文环境或许没有问题,但如果发信方用的编码格式跟你不一样,这样就会出问题,比如对方是UTF-8编码,而自己的默认编码是GB2312。

另外一种情况就是对于Base64编码的二进制数据,比如邮件中的图片等,原代码的方式更是成问题,我们的Encoding.Default 编码会破坏原始的二进制字节信息,但这些信息又想作为字符串在系统中使用,该怎么办呢?

二进制字节都是8位编码的,只有采用8位编码格式的方案才可以完整保留二进制数据。在所有的系统编码中,ISO8859-1 是8位编码,所以我们采用它来作为系统中

byte[] <=> String

转换的桥梁,我对原始代码做了修改,成为下面的样子:

 public static string Decode(string base64Encoded)
        {
 //有可能因为二进制问题不能正确解码 bluedoctor,2010.12.15
 //return Encoding.Default.GetString(DecodeToBytes(base64Encoded));
 //ISO8859-1 字符串,8位,只有这种可以完整保留二进制
            Encoding _encoding = Encoding.GetEncoding(28591);
 return _encoding.GetString(DecodeToBytes(base64Encoded));
        }

对系统中所有类似的地方进行修改,OpenPOP组件终于可以安全的处理多种格式的邮件了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逆向技术

异常处理第二讲,结构化异常(微软未公开)

            异常处理第二讲,结构化异常(微软未公开) 讲解之前,请熟悉WinDbg的使用,工具使用的博客链接 一丶认识段寄存器FS的内容,以及作用 ...

2267
来自专栏Python

仿照wtform自定义Form组件

仿照wtforms自定义Form组件 1.wtforms 点击查看源码分析及使用方法 2.自定义Form组件 #!usr/bin/env python # -*...

2297
来自专栏恰童鞋骚年

设计模式的征途—17.模板方法(Template Method)模式

在现实生活中,很多事情都需要经过几个步骤才能完成,例如请客吃饭,无论吃什么,一般都包含:点单、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是:点单=>吃东...

903
来自专栏积累沉淀

linux学习之sed命令总结

sed工具的使用 grep工具的功能其实还不够强大,grep实现的只是查找功能,而它却不能实现把查找的内容替换掉。以前用vim的时候,可以查找也可以替换,但是只...

2038
来自专栏jojo的技术小屋

原 荐 自己写JSON编辑器

作者:汪娇娇 时间:2018年1月15日 下一篇:自己写代码对比工具 时间过得好快,一下子就2018年了,想起好久没写博客,不觉有些浪费了时光,今天便来补一篇。...

8967
来自专栏Java成神之路

【转】零基础写Java知乎爬虫之进阶篇

说到爬虫,使用Java本身自带的URLConnection可以实现一些基本的抓取页面的功能,但是对于一些比较高级的功能,比如重定向的处理,HTML标记的去除,仅...

1233
来自专栏吴裕超

大搜车知乎live中的面试题结题方法记录

1、HTML&CSS(分别10分) 1. 一个div,宽度是100px,此时设置padding是20px,添加一个什么css属性可以让div的实际宽度仍然保持在...

55611
来自专栏Java技术分享

XML基本语法

 导入一个XML文件可分为如下几部分内容:文档声明 、元素、属性、注释 、CDATA区 ,特殊字符 、处理指令

25210
来自专栏Golang语言社区

Golang视角下的设计模式

这篇文章想聊聊Golang语言下的设计模式问题,我觉得这个话题还是比较有意思的。Golang没有像java那样对设计模式疯狂的迷恋,而是摆出了一份“看庭前花开花...

3879
来自专栏盛国存的专栏

A Bite of GoLang(中)

上述的 v 就称为局部变量, sum 称为自由变量,`func(v int) int {

6407

扫码关注云+社区

领取腾讯云代金券