yss*_*sup 6 sort unicode macos
我正在使用sort
命令对我从这个站点下载的 rockyou.txt 词表进行排序:
% sort rockyou.txt > rockyou_sorted.txt
Run Code Online (Sandbox Code Playgroud)
然而,当我再检查这两个文件的文件大小,它们之间的区别,在 排序文件更小:
% du -shk rockyou_sorted.txt rockyou.txt
147520 rockyou_sorted.txt
148304 rockyou.txt
Run Code Online (Sandbox Code Playgroud)
有趣的是,当我使用从这里下载的干净版本的rockyou.txt wordlist 重复这些相同的步骤时,我得到了相反的结果,即排序后的文件更大:
% sort rockyou_cleaned.txt > rockyou_cleaned_sorted.txt
% du -shk rockyou_cleaned_sorted.txt rockyou_cleaned.txt
114752 rockyou_cleaned_sorted.txt
102104 rockyou_cleaned.txt
Run Code Online (Sandbox Code Playgroud)
我想知道这是为什么?有人可以为我解释一下吗?难道我做错了什么?我认为两个文件,排序后的文件和原始文件的大小应该相同,不是吗?
更新 1,根据以下 Francesco Lucianò 的评论:使用此sort
命令和 -o 参数
% sort rockyou.txt -o rockyou_sorted_sO.txt
% du -shk rockyou_sorted_sO.txt rockyou.txt
147996 /Users/Martin/Downloads/rockyou_sorted_sO.txt
148304 /Users/Martin/Downloads/rockyou.txt
Run Code Online (Sandbox Code Playgroud)
排序后的文件仍然比原始文件小,但没有我使用sort
上面的命令版本时那么多。
所有文件中的行数相同:
% wc -l rockyou_sorted_sO.txt rockyou_sorted.txt rockyou.txt
14344391 rockyou_sorted_sO.txt
14344391 rockyou_sorted.txt
14344391 rockyou.txt
43033173 total
Run Code Online (Sandbox Code Playgroud)
更新 2,根据 bey0nd 下面的评论:
set | grep LANG
根本不输出任何内容:
% set | grep LANG
%
% chardet rockyou*
zsh: command not found: chardet
% uchardet rockyou*
rockyou.txt: UTF-8
rockyou_sorted.txt: UTF-8
rockyou_sorted_duplicut.txt: UTF-8
rockyou_sorted_sO.txt: UTF-8
Run Code Online (Sandbox Code Playgroud)
更新 3,根据以下 steeldriver 的评论:
% system_profiler SPSoftwareDataType
Software:
System Software Overview:
System Version: macOS 10.15.4 (19E287)
Kernel Version: Darwin 19.4.0
Boot Volume: Macintosh HD
Boot Mode: Normal
Computer Name: *REDACTED* MacBook Pro
User Name: *REDACTED*
Secure Virtual Memory: Enabled
System Integrity Protection: Enabled
Time since boot: 6 days 4:57
Run Code Online (Sandbox Code Playgroud)
文件系统是APFS。
更新 4,根据下面 roaima 的评论:
% ls -l rockyou*
-rw-r--r--@ 1 **REDACTED** staff 139921497 May 16 12:24 rockyou.txt
-rw-r--r-- 1 **REDACTED** staff 139921847 May 16 12:25 rockyou_sorted.txt
-rw-r--r-- 1 **REDACTED** staff 139919642 May 16 12:29 rockyou_sorted_duplicut.txt
-rw-r--r-- 1 **REDACTED** staff 139921847 May 16 13:19 rockyou_sorted_sO.txt
% stat -f .
.
Run Code Online (Sandbox Code Playgroud)
更新 5,根据以下艾萨克的评论:
% head -n3 rockyou.txt | od -An -tcx1
1 2 3 4 5 6 \n 1 2 3 4 5 \n 1 2 3
31 32 33 34 35 36 0a 31 32 33 34 35 0a 31 32 33
4 5 6 7 8 9 \n
34 35 36 37 38 39 0a
% LC_ALL=C sort rockyou.txt >rockyou_sorted_with_LC.txt
% du -shk rockyou_sorted_with_LC.txt rockyou.txt
147520 rockyou_sorted_with_LC.txt
140476 rockyou.txt
% wc -l rockyou_sorted_with_LC.txt rockyou.txt
14344391 rockyou_sorted_with_LC.txt
14344391 rockyou.txt
28688782 total
Run Code Online (Sandbox Code Playgroud)
更新 6,根据以下 fra-san 的评论:
% sort --version
2.3-Apple (101.40.1)
% locale
LANG=""
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL="en_US.UTF-8"
Run Code Online (Sandbox Code Playgroud)
这里发生了两件事,而且它们的作用有些相反。
\nsort
有效的 UTF-8。这使得文件更大。这会影响ls -l
报告的大小。du -shk
报告的大小,并且主要使其变小(但可以采用任何一种方式)。我可以对第一点给出比第二点更准确的解释,尽管简短的答案是这du
不是测量单个文件大小的正确工具,尤其是在 APFS 上。
接下来的两节将深入探讨这两个因素。
\n对于因素 (1),文件包含非 UTF-8 编码的行,UTF-8 是 macOS 上的默认区域设置编码。该sort
命令在输出时修改这些编码错误的行,从而使文件变得更大。我们将在下面进一步调查,但这只是简短的答案,如果足够了,您可以跳到下一部分。
如果我们在 C 语言环境中对提供的文件进行排序,然后再次在 en_US.UTF-8 语言环境中排序,则这两个文件具有不同的实际大小:
\n139921497 rockyou.txt\n139921497 rockyou_c.txt\n139921847 rockyou_sorted.txt\n
Run Code Online (Sandbox Code Playgroud)\nC 排序文件和 UTF-8 排序文件之间的第一个区别是
\n299c299\n< \xef\xbf\xbdR3CKL3$$\xef\xbf\xbd\n---\n> R3CKL3$$\n
Run Code Online (Sandbox Code Playgroud)\n第一行在密码的开头和结尾处包含字节 0x93 和 0x94,它们不是 UTF-8 中的有效独立字节(它们只能显示为多字节字符的连续字节)。第二个包含 Unicode 代码点 U+0093 和 U+0094,分别编码为两个字节的 UTF-8,C2 93
以及C2 94
.
结果是原来的十字节行被写成了十二字节行。在整个文件中,这些更改在排序后的文件中比原始文件增加了 350 个额外字节。
\n\n我相信这里发生的是:
\n\xe2\x80\x9cR3CKL3$$\xe2\x80\x9d
(包括引号)以Windows-1252 代码页(cp1252) 进行编码。该编码中的成对引号是 0x93 和 0x94。C2 80
- 8中的多字节编码来表示。C2 BF
C3 80
C3 BF
该网站上的其他问题讨论了如何在事后修复错误编码的 cp1252 文件(如果您需要的话)。
\nPOSIX 指出,如果行包含在语言环境中不形成有效字符的字节序列,则实用程序的行为是未定义的,因此这是标准严格允许的,并且不是一致性错误。这至少仍然是出乎意料的,并且可以说是一个行为错误。我尝试过的其他实现不会以这种方式运行。
\n这个因素导致文件变得稍微大一些,并且真正变大 - 如果您从文件中读取,您将获得更多字节。
\n因素(2)总体上推动文件变得“更小”,但这有点幻觉。读取文件不一定会产生更多或更少的字节,只是因为du
它们的大小不同。
du -shk
一般来说,这不是检查文件大小的合适方法,因为
\n\ndu 实用程序显示每个文件参数的文件系统块使用情况
\n
这意味着它报告有关文件占用了多少物理空间的信息,而不是其逻辑大小。根据文件系统和相关文件的具体参数,块计数可能与您的预期有很大差异。有,块计数很有用,例如当您将文件压缩到完整设备上时,但通常情况下并不如此。
\n如今块计数不再那么有用的原因之一是现代文件系统并不总是完全按照给定的方式写入数据:例如,它们可能会在将数据存储到更大或更小范围之前默默地压缩它,需要更少的块,或者在内部留下空白空间使用更多块使将来的插入更容易。稀疏文件省略了零块,但重复数据删除的作用甚至不止于此。
\n就 APFS 而言,它支持多种算法的压缩、一些重复数据删除和增量编码、加密和高级元数据。其中一些或全部可能正在发挥作用,最有可能的是写入文件时透明压缩的变化,具体取决于应用程序实现和系统负载。
\n如果我们只cat
检查文件几次,我们就可以看到差异。如果我已经下载rockyou.txt
了curl -O
:
cat rockyou.txt > rockyou2.txt
创建一个具有相同字节数(139921497)但块数不同的文件(创建的文件为 147504,\'scurl
为 147460 )cat
cp
(150512)一样。我不知道具体原因,也不确定是否有合理的方法来说明。我怀疑它有时比其他时候更努力地压缩数据。在所有情况下,文件的大小实际上相同,并且从任何版本读取都会返回相同的字节。我们只是没有从 APFS 或其他现代高性能文件系统上报告的块计数中获得太多有用的信息。如果您将文件压缩到设备上,尝试几次以获得最小版本可能会有所帮助,但否则就不值得考虑。
\n总体而言,我们遇到了一个编码问题,该问题使文件确实稍大一些,并通过文件系统行为进行平衡,该行为稍微修改了该较大文件的报告块计数,使其在测试中较小。真实大小测量显示排序后一致增加 350 字节。根据你如何看待它,这可能是排序上的错误,也可能是使用中的错误排序时的错误。
\n 归档时间: |
|
查看次数: |
295 次 |
最近记录: |