《Java安全编码标准》一2.13 IDS12-J在不同的字符编码中无损转换字符串数据-阿里云开发者社区

开发者社区> 华章计算机> 正文

《Java安全编码标准》一2.13 IDS12-J在不同的字符编码中无损转换字符串数据

简介: 本节书摘来自华章出版社《Java安全编码标准》一书中的第2章,第2.13节,作者 (美)Fred Long,Dhruv Mohindra,Robert C. Seacord,Dean F. Sutherland,David Svoboda,更多章节内容可以访问云栖社区“华章计算机”公众号查看
+关注继续查看

2.13 IDS12-J在不同的字符编码中无损转换字符串数据

在String对象之间进行转换时,如果涉及不同的编码类型,可能会导致数据丢失。
根据Java API[API 2006] 对?String.getBytes(Charset)方法的描述:
该方法总会替代那些错误格式的输入和不可映射的字符序列,把它们替换成这些字符的字节数组。
当必须将一个String转化为字节数组时,例如写入一个文件,并且在这个字符串中含有不可映射的字符序列的时候,就必须进行正确的字符编码。

2.13.1 不符合规则的代码示例

当String包含那些指定在charset中不能正常表示的字符时,这个不符合规则的代码示例[Hornig 2007]会破坏数据。

// Corrupts data on errors
public static byte[] toCodePage_bad(String charset, String string)
??throws UnsupportedEncodingException {
??return string.getBytes(charset);
}

// Fails to detect corrupt data
public static String fromCodePage_bad(String charset, byte[] bytes)
??throws UnsupportedEncodingException {
??return new String(bytes, charset);
}

2.13.2 符合规则的方案

java.nio.charset.CharsetEncoder类可以将一个16位的Unicode字符转换为指定Charset的一组字节数据。java.nio.charset.Character-Decoder用来完成相反的过程[API 2006]。具体的详情可以参考规则FIO11-J。
这个方案[Hornig 2007]使用了CharsetEncoder?和?CharsetDecoder两个类来处理编码转换问题。

public static byte[] toCodePage_good(String charset, String string)
??throws IOException {
??
??Charset cs = Charset.forName(charset);
??CharsetEncoder coder = cs.newEncoder();
??ByteBuffer bytebuf = coder.encode(CharBuffer.wrap(string));
??byte[] bytes = new byte[bytebuf.limit()];
??bytebuf.get(bytes);
??return bytes;
}

public static String fromCodePage_good(String charset,byte[] bytes)
??throws CharacterCodingException {
??
??Charset cs = Charset.forName(charset);
??CharsetDecoder coder = cs.newDecoder();
??CharBuffer charbuf = coder.decode(ByteBuffer.wrap(bytes));
??return charbuf.toString();
}

2.13.3 不符合规则的代码示例

这个代码示例[Hornig 2007]想要将一个字符串以特殊的编码方式附加到一个文本文件上,但这样会导致错误,因为String中可能包含无法正确表示的字符。

// Corrupts data on errors
public static void toFile_bad(String charset, String filename,
??????????????????????????????String string) throws IOException {
??
??FileOutputStream stream = new FileOutputStream(filename, true);
??OutputStreamWriter writer = new OutputStreamWriter(stream, charset);
??writer.write(string, 0, string.length());
??writer.close();
}

2.13.4 符合规则的方案

这个方案[Hornig 2007]使用CharsetEncoder?类来完成所需要的功能。

public static void toFile_good(String filename, String string,
??????????????????????????????????????String charset) throws IOException {
??
??Charset cs = Charset.forName(charset);
??CharsetEncoder coder = cs.newEncoder();
??FileOutputStream stream = new FileOutputStream(filename, true);
??OutputStreamWriter writer = new OutputStreamWriter(stream, coder);
??writer.write(string, 0, string.length());
??writer.close();
}

可以使用FileInputStream?和InputStreamReader对象来从文件中读取数据。这个InputStreamReader对象接受可选的CharsetDecoder作为参数,但这个参数必须和前面写入文件时保持一致。

2.13.5 风险评估

使用非标准化的方法来处理和字符集转换相关的问题,通常会导致数据丢失。
image

2.13.6 相关规范

image

2.13.7 参考书目

image

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 2.9 总结
与此同时,读者还学习了一些基本的计算机编程概念,如编译器、解释器、块、语句和变量。随着后续章节的学习,读者将会对这些概念越来越清晰。只要读者在本章成功地运行了Saluton程序,就可以进入下一章。
1231 0
Java基础-21总结字符流,IO流编码问题,实用案例必做一遍
你需要的是什么,直接评论留言。 获取更多资源加微信公众号“Java帮帮” (是公众号,不是微信好友哦) 还有“Java帮帮”今日头条号,技术文章与新闻,每日更新,欢迎阅读 学习交流请加Java帮帮交流QQ群553841695 分享是一种美德,分享更快乐! 1:字符流(掌握)  // 字节流读取中文可能出现的小问题(所以用字
1530 0
《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 2.12 练习
如果想更多地探索本章介绍的主题,可完成下列练习。 将英文短语“Hello world!”翻译成其他语言,翻译时可以使用谷歌翻译,编写一个程序,让计算机用法语、意大利语或葡萄牙语向世界问候。
1349 0
《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 第6章 使用字符串来交流 6.1 在字符串中存储文本
Java程序将字符串作为与用户交流的主要方式。字符串是一组文本,可以包含字母、数字、标点符号及其他字符。本章将介绍如何在Java程序中使用字符串。
1136 0
《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 2.8 运行Java程序
要查看Saluton程序的结果是否如你所愿,可使用Java虚拟机(JVM)运行类文件,JVM就是运行所有Java代码的解释器。在NetBeans中,选择菜单命令Run->Run File。在源代码编辑器的下面将会打开输出面板。如果没有错误,则该程序会在该面板中显示输出结果,如图2.3所示。
1372 0
10059
文章
0
问答
来源圈子
更多
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载