最近在Android上的一个项目中需要用到VCard的一些东西,发现其中有一部分关于Quoted-Printable编码的部分稍微有点棘手,主要是看起来规则比较复杂,在网上搜索一下中文翻译的都很简单,看原版E文的,又觉得有些晦涩。在一个开源项目中看到一个关于QuotedPrintable的类,但是只写了decode部分,我按照自己的理解把那个类补充了一下,加入了encode功能。

QP编码规则中关于空格和TAB部分,有点复杂,其实搞得人头晕,实际上可以简单处理,把空格和TAB也当做要转化成=XX格式的字符处理就ok了,就不用再去考虑空格和TAB在行尾的情况了。

在网上看了一些朋友的示例代码,但大多都没有处理76字符的行长度限制,我给加上了。

下面是代码:

import java.io.UnsupportedEncodingException; import android.util.Log; /** * A class containing static methods to perform decoding from <b>quoted * printable</b> content transfer encoding and to encode into */ public class QuotedPrintable { private final static byte TAB = 0x09; // /t private final static byte LF = 0x0A; // /n private final static byte CR = 0x0D; // /r private final static byte SPACE = 0x20; // ' ' private final static byte EQUALS = 0x3D; // '=' private final static byte LIT_START = 0x21; private final static byte LIT_END = 0x7e; private final static int MAX_LINE_LENGTH = 76; private static int mCurrentLineLength = 0; /** * A method to decode quoted printable encoded data. * It overrides the same input byte array to save memory. Can be done * because the result is surely smaller than the input. * * @param qp * a byte array to decode. * @return the length of the decoded array. */ public static int decode(byte [] qp) { int qplen = qp.length; int retlen = 0; for (int i=0; i < qplen; i++) { // Handle encoded chars if (qp[i] == '=') { if (qplen - i > 2) { // The sequence can be complete, check it if (qp[i+1] == CR && qp[i+2] == LF) { // soft line break, ignore it i += 2; continue; } else if (isHexDigit(qp[i+1]) && isHexDigit(qp[i+2]) ) { // convert the number into an integer, taking // the ascii digits stored in the array. qp[retlen++]=(byte)(getHexValue(qp[i+1])*16 + getHexValue(qp[i+2])); i += 2; continue; } else { Log.e("DEBUG", "decode: Invalid sequence = " + qp[i+1] + qp[i+2]); } } // In all wrong cases leave the original bytes // (see RFC 2045). They can be incomplete sequence, // or a '=' followed by non hex digit. } // RFC 2045 says to exclude control characters mistakenly // present (unencoded) in the encoded stream. // As an exception, we keep unencoded tabs (0x09) if( (qp[i] >= 0x20 && qp[i] <= 0x7f) || qp[i] == TAB || qp[i] == CR || qp[i] == LF) { qp[retlen++] = qp[i]; } } return retlen; } private static boolean isHexDigit(byte b) { return ( (b>=0x30 && b<=0x39) || (b>=0x41&&b<=0x46) ); } private static byte getHexValue(byte b) { return (byte)Character.digit((char)b, 16); } /** * * @param qp Byte array to decode * @param enc The character encoding of the returned string * @return The decoded string. */ public static String decode(byte[] qp, String enc) { int len=decode(qp); try { return new String(qp, 0, len, enc); } catch (UnsupportedEncodingException e) { return new String(qp, 0, len); } } /** * A method to encode data in quoted printable * * @param content * The string to be encoded * @param enc * The character encoding of the content string * @return The encoded string. If the content is null, return null. */ public static String encode(String content, String enc) { if (content == null) return null; byte[] str = null; try { str = content.getBytes(enc); } catch (UnsupportedEncodingException e) { str = content.getBytes(); } return encode(str); } /** * A method to encode data in quoted printable * * @param content * The byte array of the string to be encoded * @return The encoded string. If the content is null, return null. */ public static String encode(byte[] content) { if (content == null) return null; StringBuilder out = new StringBuilder(); mCurrentLineLength = 0; int requiredLength = 0; for (int index = 0; index < content.length; index++) { byte c = content[index]; if (c >= LIT_START && c <= LIT_END && c != EQUALS) { requiredLength = 1; checkLineLength(requiredLength, out); out.append((char)c); } else { requiredLength = 3; checkLineLength(requiredLength, out); out.append('='); out.append(String.format("%02X", c)); } } return out.toString(); } private static void checkLineLength(int required, StringBuilder out) { if (required + mCurrentLineLength > MAX_LINE_LENGTH - 1) { out.append("=/r/n"); mCurrentLineLength = required; } else mCurrentLineLength += required; } }

用于Quoted-Printable编解码的JAVA类相关推荐

  1. Jva编解码,加密工具类大全(Base64编解码,URL 编解码,sha56_Hmac加密,MD5对字符串进行加密,java自带类实现SHA-256方式加密)

    Base64编解码 /*** Base64编码.*/public static String encodeBase64(byte[] input) {return new String(Base64. ...

  2. js编码java解码_JS编解码与Java编解码的对应关系

    最近前段在导出数据时会遇到"illegal character"的异常错误,结果发现是在请求地址中请求参数包含了空白字符(其编码为%C2%A0)或者是空格字符(其编码为%20),之 ...

  3. C语言使用 ASN.1对报文进行编解码(将c函数封装成类简化使用)

    文章目录 1.为什么要报文编解码 2.ASN.1是什么 3.使用函数介绍 4.对数据进行编解码 5.C语言使用 6.将上述函数封装成c++类 1.为什么要报文编解码 两台机器通信: 1.两台机器的操作 ...

  4. 【Apache Mina2.0开发之二】自定义实现Server/Client端的编解码工厂(自定义编码与解码器)!...

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/apache-mina/831.html ☞ ...

  5. H264视频传输、编解码----FFmpeg软解码

    记录一下之前项目的实际使用过程. 将按照Java层------>JNI接口------>JNI代码中使用FFmpeg解码. 首先Java层: public class CodecWrapp ...

  6. 通过Windows DShow获取设备名、支持的编解码及视频size列表实现

    之前在https://blog.csdn.net/fengbingchun/article/details/102641967中介绍过通过DShow获取Camera视频的实现,即调用VideoCapt ...

  7. iOS之ffmpeg开发音视频编解码概要、SDL

    官网:http://ffmpeg.org/documentation.html http://ffmpeg.org/ffmpeg.html 简介:https://blog.csdn.net/qq_36 ...

  8. WebRTC android 端支持H264编解码

    一.WebRTC源码中默认使用的H264编解码的库 1.WebRTC源码的video_coding模块中,包含了H264编解码相关的类 打开画红线的两个头文件,分别可以看到解码类中导入了ffmpeg的 ...

  9. 使用日本人的库QRCode编解码二维码

    慕课网讲解 http://www.imooc.com/learn/531 首先导入其jar包. 1.首先建立一个实现QRCodeImage的类 /*** @FileName: QRCodeImageB ...

最新文章

  1. FFmpeg中libswresample库简介及测试代码
  2. 安装 Linux -Mplayer 播放器
  3. 网站单页面排名提升的技巧有哪些?
  4. pyhton中的魔术方法
  5. ThreadLocal介绍以及源码分析
  6. 设计模式在项目中的应用案例_设计模式在项目中的应用(初学者版)
  7. CentOS上安装软件错误提示:configure: error: no acceptable C compiler found in $PATH
  8. linux命令ps -aux|grep xxx详解
  9. 算法:回溯五 数组全排列permutations
  10. 三级数据库常考知识点强调
  11. jQuery WeUI动态获取省地市三级联动
  12. 服务器 python cant open file_QQ炫舞转服系统-QQ炫舞官方网站-腾讯游戏
  13. 实例:用C#.NET手把手教你做微信公众号开发(1)--接入
  14. boj 1348 网络流,从来没有一个网络流能让我如此泪流满面,这样的建图方式,仰慕dalong
  15. 7类 登录/注册 安全漏洞
  16. echart显示多组数据
  17. Excel数据透视表经典教程二《创建数据透视表》
  18. 安卓编程用什么软件_如何用手机进行编程?有哪些值得推荐的软件?
  19. 嵌入式linux/鸿蒙开发板(IMX6ULL)开发流程(六)烧写整个系统或更新部分系统
  20. 上海应用技术大学计算机专业分数线,上海应用技术大学历年分数线 2021上海应用技术大学录取分数线...

热门文章

  1. sso统一认证postMessage无感处理
  2. Python数据分析初体验
  3. excel学习--从基础开始1
  4. 【算法】数组左旋、字符串左旋
  5. Notepad++中格式化html代码的插件tidy2的下载与安装
  6. COMBO光驱+Mplayer播放DVD(转)
  7. 对Largest函数的测试
  8. 浙大远程教育计算机第三章,2016浙大远程教育计算机应用基础作业-3
  9. tuend/stratis/vdo总结
  10. 店宝宝:京东星主播能解决明星带货痛点吗?