惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
MongoDB | Blog
MongoDB | Blog
Engineering at Meta
Engineering at Meta
云风的 BLOG
云风的 BLOG
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
T
The Exploit Database - CXSecurity.com
P
Privacy & Cybersecurity Law Blog
Know Your Adversary
Know Your Adversary
月光博客
月光博客
I
InfoQ
阮一峰的网络日志
阮一峰的网络日志
NISL@THU
NISL@THU
爱范儿
爱范儿
S
Securelist
博客园 - 叶小钗
C
CERT Recently Published Vulnerability Notes
Recorded Future
Recorded Future
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
aimingoo的专栏
aimingoo的专栏
D
DataBreaches.Net
G
GRAHAM CLULEY
P
Proofpoint News Feed
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
C
Cyber Attacks, Cyber Crime and Cyber Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tor Project blog
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Recent Announcements
Recent Announcements
P
Proofpoint News Feed
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
Jina AI
Jina AI
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
博客园 - 【当耐特】
H
Help Net Security
F
Fortinet All Blogs
T
The Blog of Author Tim Ferriss

夜行人

回家路上 第一期的直播演示项目 震动检测器 正能量 在线参观CodeLab Neverland 发布 CodeLab Adapter 3.3.1 DynamicTable 之 纸糊方向盘 CodeLab DynamicTable: 一个可实施的技术方案 CodeLab Insight 发布 Alpha 版 情人节 Home Assistant 周报 && IoT 周报 (02) Joplin: 关注隐私的 Evernote 开源替代软件 浏览器的未来与 Web 传感器 Home Assistant 周报 && IoT 周报 (01) 百宝箱(01) 论自由 介绍 WebThings Home Assistant 周报 && iot 周报 (00) 百宝箱(00) 毛姆读书心得 传世之作 周末徒步 CodeLab Adapter ❤️ Jupyter/Python 航班 躲雨 夏令营途中 [译]思想--作为一种技术 The future of coding 美国之行 三门问题的程序模拟 从Python转向Pharo https://blog.just4fun.site/post/iot/iot-open-source-projects/ Python异步编程笔记 https://blog.just4fun.site/post/iot/iot-open-source-hardware-community/ 万物积木化开发者社区 CodeLab ❤️ Blender Scratch3技术分析之云变量 API(第7篇) [译]对管道(Pipes)的偏爱 [译]提出正确的问题比得到正确答案更重要 蓝牙设备与Scratch3.0 创建你的第一个Scratch3.0 Extension Scratch3技术分析之项目内部数据(第6篇) Scratch3技术分析之社区 API(第5篇) Scratch3技术分析之User API(第4篇) Scratch3技术分析之项目主页API(第3篇) Scratch3技术分析之静态资源API(第2篇) Scratch3.0、micro:bit与Windows7 https://blog.just4fun.site/post/iot/zerynth-vs-micropython/ 核聚变、方所与半宅空间 可视化编程为何是个糟糕的主意 codelab.club周末聚会 关于codelab.club '下一件大事'是一个房间 Hungry Robot - Eat everything 编程作为一种思考方式 今日简史 史蒂夫·乔布斯传 罗素自选文集 https://blog.just4fun.site/post/edx/tianjin-scratch-ai/ https://blog.just4fun.site/post/edx/richie-cms-openedx/ 徒步武功山 WebUSB与micro:bit 积木化编程与3D场景 夜宿武功山顶 scratch3-adapter接入优必选Alpha系列机器人 https://blog.just4fun.site/post/edx/video-migration-note/ scratch3-adapter重构笔记 https://blog.just4fun.site/post/edx/edx-community-members/ 两种硬件编程风格的比较 使用micro:bit自制PPT翻页笔 柏拉图对话集 scratch3.0 + micro:bit 七月电影放映计划 非营利组织的管理 Screenly--用树莓派让任何屏幕变为可编程的数字标牌 以最佳实践开始你的Django项目 micro:bit与事件驱动 为Scratch3.0设计的插件系统(上篇) OCR应用一例 近两年读过的一些好书 blockly开发之使用python驱动浏览器中的turtle(2) 牛顿新传 文学理论入门 逻辑的引擎 人生的意义 blockly开发之生成并运行js代码(1) blockly开发之hello world(0) micro:bit使用笔记 神器之Termux https://blog.just4fun.site/post/iot/micropython-notes/ Cozmo what is this Scratch的前世今生 下段旅程 我行在远方 爆裂 途中杂记 https://blog.just4fun.site/post/edx/open-edx-startup/ cozmo系列之入门 - 有性格且可编程的机器人 PaperWeekly开发笔记 创业二三事
编码相关的笔记
2016-06-28 · via 夜行人

编码/解码问题是个大坑,其中的复杂性,大多来自历史包袱

由于计算机领域的分层架构和多平台问题,这个问题被进一步加剧,unicode的出现,给这个问题带来了曙光.

可是生活不总是那么美好的,有些时候,一不小心,我们还是会掉到满是泥沼的坑里

周末在凤凰书城看一本数据清洗相关的书,其中说道噪声数据的问题,有问题的编码是噪声的来源之一,书中分享了不少好用的方法,在便签里记了一些,加上之前笔记里的,正好整理成一篇文章

编码问题

这里引《中文编码杂谈》中关于乱码的讨论

在Linux平台上如果使用cat等命令查看文件中的中文内容时,可能出现乱码。这也是编码的问题。简单的说是文件时按照A编码保存,但是cat命令按照当前Locale设定的B编码去查看,在B和A不兼容的时候就出现了乱码。

核心概念

十分钟搞清字符集和字符编码

字符集

简单的说字符集就规定了某个文字对应的二进制数字存放方式(编码)和某串二进制数值代表了哪个文字(解码)的转换关系

字符编码

字符编码(英语:Character encoding)、字集码是把字符集中的字符编码为指定集合中某一对象(例如:比特模式、自然数序列、8位组或者电脉冲),以便文本在计算机中存储和通过通信网络的传递。常见的例子包括将拉丁字母表编码成摩斯电码和ASCII。其中,ASCII将字母、数字和其它符号编号,并用7比特的二进制来表示这个整数 –wikipedia

Unicode和UTF-8

Unicode对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。

Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储

而UTF-8就是字符编码,是Unicode规则字库的一种实现形式

Python中的编码问题

Python编码和Unicode一文中描述了python中可能出现的一些编解码难题

原因之一是Python 2.x默认将所有的字符串当做ASCII来对待(python3中会好很多)

当你使用string类型时,实际上会储存一个字节串

解码字节流

你可以把字节流解码(decode)成一个Unicode对象,把一个Unicode 对象编码(encode)为字节流

  • 你最好是尽早的将字节流解码为Unicode(字节流进入程序的时候)
  • 你不能简单地输出一个Unicode对象。它必须在输出前被变成一个字节串

str/unicode

在mac下python2.7.5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# unicode
unicode_a = u"你好"
type(unicode_a) # <type 'unicode'>
unicode_a # u'\u4f60\u597d'
unicode_b = u'\u4f60\u597d' 
unicode_b # u'\u4f60\u597d'
unicode_a == unicode_b # True

# unicode_c = unicode("你好") python2会报错,python会把所有东西作为字节流理解
u'hello' == unicode("hello") #  True,如果

unicode_a.encode("utf-8") # '\xe4\xbd\xa0\xe5\xa5\xbd'
################
# str
str_a = "你好"
str_a # '\xe4\xbd\xa0\xe5\xa5\xbd'
str_a.decode("utf-8") # u'\u4f60\u597d'
str_a.decode("utf-8")  ==  u"你好" # True

__repr__的目标是准确性,__str__的目标是可读性

codecs模块

codecs模块能在处理字节流的时候提供很大帮助。你可以用定义的编码来打开文件并且你从文件里读取的内容会被自动转化为Unicode对象。

读写文件

当从一个文件读取数据的时候,codecs.open 会创建一个文件对象能够自动将utf-8编码文件转化为一个Unicode对象,而写入文件这样写:

1
2
3
4
import codecs
fh = codecs.open("/tmp/utf-8.txt", "w", "utf-8")
fh.write(u"\u2013") 
fh.close()

使用urllib流

1
2
3
4
stream = urllib.urlopen("http://www.google.com")
Reader = codecs.getreader("utf-8")
fh = Reader(stream)
type(fh.read(1)) # <type 'unicode'> ,应该尽可能让程序内部的数据都是 <type 'unicode'> 

你必须对codecs模块十分小心。你传进去的东西必须是一个Unicode对象,否则它会自动将字节流作为ASCII进行解码。

策略

python编解码涉及的问题可能很多,上至大神下至小白,都可能受扰,为了保持简单,我们可以保持这样一种习惯:关注输入输出,内部保持unicode。

每当有数据进入程序,将其解码(decode)为unicode(utf-8)

当有数据从程序中输出时,将其编码(encode)为utf-8

最佳实践:

  • 最先解码(解码为unicode对象),最后编码(输出为字节码)
    • 最先解码意味着无论何时有字节流输入,需要尽早将输入解码为Unicode
    • 最后编码意味着只有你打算将文本输出到某个地方时,才把它编码为字节流。这个输出可能是一个文件,一个数据库,一个socket等等
  • 默认使用utf-8编码
  • 使用codecs和Unicode对象来简化处理
    • codecs模块能够让我们在处理诸如文件或socket这样的流的时候能少踩一些坑。如果没有codecs提供的这个工具,你就必须将文件内容读取为字节流,然后将这个字节流解码为Unicode对象。
    • codecs模块能够让你快速的将字节流转化为Unicode对象,省去很多麻烦。

linux下的一些工具

file

file命令用来探测给定文件的类型,

参数:

  • -i:显示MIME类别。
  • -c:详细显示指令执行过程,便于排错或分析程序执行的情形;

file *

iconv

conv命令是用来转换文件的编码方式的,比如它可以将UTF8编码的转换成GB18030的编码

iconv -f encoding -t encoding inputfile

iconv -f UTF-8 -t GBK file1 -o file2 //将一个UTF-8 编码的文件转换成GBK编码

chardet

有时候我们不知道文件/字节流采用了什么编码,可以让chardet来猜测编码,chardet是python的一个库

###传输编码语法(transfer encoding syntax) 用于处理上一层次的字符编码方案提供的字节序列。一般其功能包括两种:一是把字节序列的值映射到一套更受限制的值域内,以满足传输环境的限制,例如Email传输时Base64或者quoted-printable,都是把8位的字节编码为7位长的数据;另一是压缩字节序列的值,如LZW或者进程长度编码等无损压缩技术。

######Base64编码 base64编码相关的部分,可以翻阅我的JWT学习笔记中的附录部分

  • Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据

  • 常用于在URL、Cookie、网页中传输少量二进制数据。

所谓Base64,就是说选出64个字符—-小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"(再加上作为垫字的"=",实际上是65个字符)—-作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。

关于base64更多的细节可以参考维基百科和Base64笔记

在python中实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import base64
base64.b64encode('hello') #aGVsbG8=  , 被编码的不是应该是二进制数据吧,python的二进制默认被解析为ascii?,在这里hello无论是b'hello'还是'hello'/u'hello',结果都一样
base64.b64decode("aGVsbG8=") # hello

a = u'你好' # \u4f60\u597d
b = base64.b64encode(a.encode("utf-8"))  #5L2g5aW9
c = base64.b64decode(b) # \xe4\xbd\xa0\xe5\xa5\xbd
c.decode("utf-8") # u'\u4f60\u597d'

# 由于标准的Base64编码后可能出现字符+和/,在URL中就不能直接作为参数,所以又有一种"url safe"的base64编码,其实就是把字符+和/分别变成-和_
d = u"哈里谢顿".encode("utf-8") # \xe5\x93\x88\xe9\x87\x8c\xe8\xb0\xa2\xe9\xa1\xbf
base64.b64encode(d) # 5ZOI6YeM6LCi6aG/ , 有反斜杠
e = base64.urlsafe_b64encode(d) # 5ZOI6YeM6LCi6aG_
base64.urlsafe_b64decode(e) # \xe5\x93\x88\xe9\x87\x8c\xe8\xb0\xa2\xe9\xa1\xbf

url中的编码问题

一般而言使用urllib库中的urlencode函数就好了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from urllib import urlencode
data = {
     'name': '小明', #u'小明'则需要encode为字节码
     'age': '10岁'
     }
print urlencode(data) # age=10%E5%B2%81&name=%E5%B0%8F%E6%98%8E

#仅对字符串进行转码可以使用quote
from urllib import quote
quote('小明')  #%E5%B0%8F%E6%98%8E'

如果有大量此类工作可以考虑使用furl

在线工具

一些细碎知识

Windows简体中文版中,ANSI是默认的编码方式。对于英文文件是ASCII编码,对于简体中文文件是GB2312编码(繁体中文版会采用Big5码)

python中字节流和unicode的代码视角比较

参考