相同的压缩密码,会不会因为计算机编码技术以及 unicode 代码点的变更,导致未来解不开压缩包?

345 天前
 bler

unicode 给世界上所有的语言字符编号,编码方式决定了二进制的序列,hash 函数通过二进制生成散列值, 那么哪天操作系统不采用这种编码方式了,编码出的二进制序列不同,那么散列值也不一样了,那不就解不开压缩报了?

比如中文”我“,使用 utf8 和 GBK 编码出的二进制序列是不一样的,压缩软件是如何判定输入的字符的编码方式的, 是使用操作系统的编码方式吗

不知道描述的对不对,有对编码熟悉的大佬说说吗

2872 次点击
所在节点    程序员
35 条回复
jiangwei2222
345 天前
压缩和编码是两码事,编码这种东西也只可能出现新的,不可能改老的。
mcfog
345 天前
能在短短几行字里聊出那么多认知错误也是不简单
lilei2023
345 天前
@mcfog 哈哈!
bler
345 天前
@mcfog 大佬详细说说,就是不懂才问
AoEiuV020JP
345 天前
换新的编码肯定会有新的名字,不可能出出个新的 unicode 完全取代现有的 unicode 然后还叫 unicode ,
软件判定或者说计算肯定是基于编码后的二进制内容,不管是什么编码方式不管明文是什么,只要编码后二进制是对的就能解,
lambdaq
345 天前
@bler 你没搞懂的只有一个点。。。unicode 不是一个编码,是一系列编码的统称。。所以 unicode 一般都要先声明自己是哪一套编码。。。
eGlhb2Jhb2Jhbw
345 天前
除了上边说的,根据你提到压缩包,以及解压密码,我推测你说的是文件解压缩,文件解压缩和文件内容和编码没太大关系,是在“文件”这个层面上进行解压缩的。
thinkershare
345 天前
1. Unicode 字符集: 每个字符对应的码点不会变化(只会添加新的 Code)
2. UTF-8/16/32: 是存储方案(编码方案),也不会变化,只会添加对新的 Unicode 字符集版本的支持。
3. 压缩软件没有办法知道用的什么格式,要不再元数据携带,要不最终用户告诉它使用的什么编码,要不靠猜测,要不靠诱探。

PS: 各个编码方案通过编码表是可以相互转换的,但是很多转换是不可行的,例如 ASCII 的字符集就很小,没法包容 UTF-8 的所有有效字符集。
e3c78a97e0f8
345 天前
同样的文字用 Unicode 的确可以有多种表示法,这个在中文里好像很难出现,但是非中文非英文有很多情况

所以一般系统的密码都限定了字符集
bler
345 天前
@thinkershare 老哥你的 1 ,2 解答了我对码点和编码的疑惑,但是第三点我很好奇,假设操作系统是 GBK 编码环境,然后软件能拿到操作系统的编码方式,输入到密码框中的数据是 GBK 编码的二进制数据,然后压缩软件把他转化成 utf8 的二进制编码值,然后再散列比对解压缩密码,这种编码的转化过程可能存在吗
thinkershare
345 天前
@bler 你理解错了,操作系统没有编码一说。字符串对操作系统来说是透明的字节序列。操作系统并不关心字节序列到底是什么编码方案,关心编码模式的是应用程序( Application),应用程序自己必须要知道你使用的字符串到底使用的什么编码,否则就无法解析。各个编程语言内置的 string 类型使用的编码都可以是不同的。例如 Python 用的 utf-8, c#/javascript 用的 UTF16 。因此这个属于应用程序需要关心了。例如你是要 C#将一个文件是要 UTF-16 写入文件,在 python 中是要 utf8 去加载这个文件,就会乱码,这个时候 python 加载这个文件必须显示告诉加载方法应该文件是要的是 UTF16 编码,这个时候 python 会将文件是要 utf-16 加载后转码为 utf-8, 从而才能在 python 中正常的处理这个字符串。
thinkershare
345 天前
@bler 另外就是,操作系统本身是由内核+驱动+一堆周边软件构成的。操作系统内核部分的确也有自己的字符串编码模式,但这个和你普通的应用程序没关系,你们也不同共享内存,除非涉及到内核调用和封送。这个时候你就需要关心操作系统内部字符串的格式了。或者你调用一些系统组件,这个时候返回给你的字节序列你必须按照操作系统的编码模式转换为你本地编程语言的字符串使用的编码格式,不知道我这样解释,你理解没有。
bler
345 天前
总结一下:
这个问题是我在设置压缩包密码时,是否应该用非 ascii 字符引出的,我担心如果未来中文出现新的文字,unicode 码点和字符的映射会发生变化。
一般来讲 ascii 字符 基本不会变化了,英文字母就那几个,中文的可变性太强了,新增文字就意味着新增码点。但是想想 unicode 委员会应该不会范这种低级错误,有点杞人忧天了。但是也不是没有收获,又加深了对编码的理解
thinkershare
345 天前
@bler 另外存在一个叫做码表或者 Encoding 的东西,它可以将不同 Encoding 编码的字节序列做相互转换,例如将一个 byte[] /utf-8 转换为 byte[] utf-16, 字符串内部都使用 byte[]序列表示。获取到一个字节序列后,如果你不知道它究竟是什么编码方案,甚至不知道它不是字符序列,就只能靠探测了。例如 VSCode 默认就会一个探测功能,可以猜测一个文件使用了什么 Encodeing 模式,但是这个探测并不是总是靠谱。
bler
345 天前
@thinkershare 谢谢老哥了,我理解你的意思,我就是好奇字符的编码对应用程序的影响,应用程序是如何应对多语言多编码环境的
thinkershare
345 天前
@bler 压缩软件会在内部使用一个固定的 encoding 模式获取到的密码的 byte[]表示,这个表示在 Encoding 指定值不变的情况下是不会有什么变化的。
另外就是 zip 这种压缩编码存在缺陷,的确会又解析错误。例如你在 GB2312 chcp 下压缩一个文件夹,然后在 UTF8 chcp 的另外一个计算机上解码,文件夹就会乱码。因为 zip 这个格式规范并没有存储压缩时候的文件名的字符串编码格式,导致它总是按照操作系统当前的编码来处理字节序列,这回导致文件名这种东西,使用 gb2312 byte 字节存储,却使用 UTF-8 解码,这个时候你就会看到解码后的文件名称错误。这个纯粹是因为 zip 这种文件格式存在缺陷。这种情况你就只能显示的告诉解压软件不要使用操作系统默认编码来解压文件,而是使用你手动指定的编码格式。
软件应该避免依赖操作系统的默认编码格式。否则你的软件很可能无法正常在各个不同国家的系统上运行。
thinkershare
345 天前
@bler 但这种粗暴的解决方案有时候也存在问题。因为某些系统,甚至不携带非 ASCII 的码表,也无法显示非 ASCII 编码的字符,这就是另外一个话题了,这些都是历史遗留问题。
k9982874
345 天前
赛博求剑?
bler
345 天前
@thinkershare 你说的这个场景我遇到过,之前有 hook 过 app ,遇到 java 的字节流数据,打印出来是一个整数数组,这个时候需要知道它的编码方式才能将他转成可阅读的文本,字节流数据你不知道编码方式,你就不知道是三个字节表示一个字符还是 2 个字节表示一个字符
vituralfuture
345 天前
压缩包只是分发文件的一种方式,而文件就是二进制数据的容器,别人收到压缩包后,解开得到一系列文件,这个文件如何解读是什么完全靠预先定义。

比如你收到一个压缩包,作者说编码是 utf-8 ,你解压后就按照 utf-8 编码打开它。或者你发现 gbk 打开乱码了,就尝试用 utf-8 打开

也就说压缩是针对二进制数据的操作,编码是对二进制数据的理解方式

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/981315

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX