天问

  • Blog
  • 热修复与动态加载
  • python爬虫
  • 专栏
    • 热修复与动态加载
    • NDK开发
    • 设计模式与架构
    • React Native
  • 好文转载
    • 计算机技术
    • 投资理财
    • 摄影与拍照技巧
  • 投稿
  • 关于本站及隐私政策
  • Github
StevenQ
为今天工作,为明天投资,为未来孵化一些东西!
  1. 首页
  2. 计算机技术
  3. python
  4. 正文

python中的字符编码问题

2017年3月28日 821点热度 2人点赞 0条评论

今天在使用python处理字符串时出现了一个如下错误

<code>unicodedecodeerror ascii codec can’t decode byte 0xd7 in position 4 ordinal not in range(128)
</code>

从字面意思来看很显然是字符编码问题,然后百度了好多解决方案,根本不靠谱,最终折腾了半天还是解决了,记录一下
还是按照国际惯例,先描述一下应用场景:在对Apk的so加密保护中,有这么一个过程,将dex通过baksmali.jar反编译后得到的smali文件中,判断用户输入的待保护的so列表soList中
的so是否被调用,我们知道用户输入的so一般形如libxxx.so的格式,而java调用语句则是System.loadLibrary(“xxx”);的形式,即去除了前面的lib和.so后缀。反映到smali代码中就是如下的形式:

<code>const-string v0, "xxx"

invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
</code>

其中的xxx就是so列表中去除了前面的lib和.so后缀的so名称。那么这里就存在一个场景就是遍历修正用户输入后的so列表,然后在smali文件中判断是否存在调用该so的代码,即是否存在形如上述两条语句的代码,那么我们需要做的某一步就是构造出上述两个语句来,即讲so列表中的so与字符串const-string v0,相连接,刚开始以为很简单,不就是如下代码就可以吗?

<code>soCode = 'const-string v0, '+'"'+loadSo+'"'
</code>

但是运行时出现开头提到的错误,很显然错误说的是编码问题,然后百度了一下,都说要在python文件开头加上utf-8注释之类的语句,或者说是使用如下语句:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

事实上没任何作用,仍然报开头提到的错误。那么我们仔细思考下为何会报那个错误,难道不应该是字符串的连接那么简单吗?事实证明不是那么简单,因为python中的list列表中存储的虽然是字符串,但是在python内部是使用unicode表示的,因此不能直接将一个list列表中的字符串与''的字符串相连接,因为这两种字符串可能属于不同的编码格式,是不能够直接相连接的,str与unicode之间的关系如下所示:

<code>str  -> decode('the_coding_of_str') -> unicode
unicode -> encode('the_coding_you_want') -> str
</code>

也就是说str是字节串,是unicode经过编码(encode)后的字节组成的,这两者之间通过 decode/encode相互转化,那么知道了具体原因自然就知道该如何解决了,代码如下

<code>soCode = 'const-string v0, '+'"'+loadSo.encode('utf-8')+'"'
</code>

将list列表中的unicode先encode为字符串,然后再与‘xxx’字符串相连接,所以以后大家遇到这个问题,就不要相信网上的谣言说在python文件开头加上utf-8的注释,一定要弄清楚处理的字符串是str类型还是unicode类型,判断方式是使用type

<code> s = '中文'  
 s = u'中文'.encode('utf-8')  
 >>> type('中文')  
 <type 'str'>

 s = u'中文'
 s = '中文'.decode('utf-8') 
 s = unicode('中文', 'utf-8')
 > > > type(u'中文') <type 'unicode'>
</code>

看似都是字符串,一个是str类型一个是unicode类型,总之要搞明白要处理的是str还是unicode, 使用对的处理方法(str.decode/unicode.encode)

一个和本内容相关的传送门:python进阶编码处理小结

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: python
最后更新:2017年4月4日

天问

追梦追自由,穷则独善其身,达则兼济天下

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2022 天问 ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang