Linux编码转换命令:iconv、dos2unix、base64、md5sum

中文乱码、Windows 传过来的脚本换行不对、需要把二进制塞进文本接口、下载的文件要校验完整性,这四类问题分别对应 iconv、dos2unix、base64、md5sum 四条命令。它们看着不搭边,实际都是在处理"字节长什么样"的问题。这一篇把用法和常见坑过一遍。

一、iconv:字符编码转换

语法格式

复制代码
iconv -f 原编码 -t 目标编码 [输入文件]

不写输入文件时从标准输入读。转换结果打到标准输出,要落盘用重定向。

常用参数

参数 说明
-f 编码 指定输入编码(from)
-t 编码 指定输出编码(to)
-l 列出所有支持的编码名
-c 丢弃无法转换的字符(不报错中断)
-t UTF-8//IGNORE 目标编码后加 //IGNORE,忽略转换不了的字节

示例与预期输出

把一份 GBK 编码的日志转成 UTF-8:

复制代码
iconv -f GBK -t UTF-8 old_gbk.log > new_utf8.log

这条命令不会有任何输出(成功就是没输出)。想确认转得对不对,用 file 看一眼:

复制代码
file new_utf8.log

预期输出:

复制代码
new_utf8.log: UTF-8 Unicode text

反向把 UTF-8 转成 GBK,给老 Windows 程序读:

复制代码
iconv -f UTF-8 -t GBK readme.txt > readme_gbk.txt

如果原文里有 GBK 表示不了的生僻字(比如某些 emoji、繁体字),iconv 会直接报错中断。这时候加 -c 跳过坏字节:

复制代码
iconv -f UTF-8 -t GBK -c readme.txt > readme_gbk.txt

代价是那些字符会消失,转换前最好先备份原文。

⚠️ 常见坑

  1. 编码名写错 :utf8 和 UTF-8 不一样,iconv 认 UTF-8。拿不准用 iconv -l | grep -i utf 查。
  2. 猜原编码 :file -i 文件名 能帮你猜,但不是 100% 准。中文乱码最常见的就是 UTF-8 和 GBK 互相转。
  3. 直接改原文件 :iconv 不支持原地编辑,一定要 > 新文件。想覆盖就先写到临时文件再 mv。

二、dos2unix / unix2dos:换行符转换

背景

Windows 的文本文件行尾是 \r\n(CRLF),Linux 是 \n(LF)。从 Windows 拷过来的 shell 脚本第一行就可能报:

复制代码
bash: ./script.sh: /bin/bash^M: bad interpreter

那个 ^M 就是多出来的 \r。

语法格式

复制代码
dos2unix [选项] 文件      # CRLF -> LF
unix2dos [选项] 文件      # LF -> CRLF

常用参数

参数 说明
-k 保持原文件时间戳不变
-n 新文件 不原地修改,输出到新文件
-q 安静模式

示例与预期输出

复制代码
dos2unix script.sh

预期输出:

复制代码
dos2unix: converting file script.sh to Unix format...

改完脚本就能直接 ./script.sh 跑了。

不想动原文件、想另存一份:

复制代码
dos2unix -n script_win.sh script_unix.sh

没有 dos2unix 命令时

最小化安装的系统可能没装这个包。用第 56 篇讲过的 tr 也能干同样的事:

复制代码
tr -d '\r' < script_win.sh > script_unix.sh

效果一样,缺点是没了批量处理和 -k 保时间戳这些便利功能。

三、base64:二进制和文本互转

语法格式

复制代码
base64 [选项] 文件

常用参数

参数 说明
-d 解码(decode)
-i 解码时忽略非法字符
-w 数字 编码后每行宽度,0 表示不折行

示例与预期输出

把图片编码成文本,塞进 JSON 配置:

复制代码
base64 -w0 logo.png > logo.b64

-w0 让输出不折行,方便塞进单行配置。logo.b64 里就是一长串 aGVsbG8... 样子的字符。

解码还原:

复制代码
base64 -d logo.b64 > logo_restored.png

再用 md5sum(下面讲)对比一下原始文件和解码后的文件,哈希值一致就说明没坏。

直接在命令行里编一段:

复制代码
echo -n "hello" | base64

预期输出:

复制代码
aGVsbG8=

-n 让 echo 不输出末尾换行,否则编出来的串会多两个字符。

⚠️ 注意

base64 不是加密,只是编码。任何人拿到串都能解回来,不要拿它当密码用。它的作用是让纯文本通道(邮件正文、JSON 字符串、HTTP header)能安全地传二进制数据。

四、md5sum:文件完整性校验

语法格式

复制代码
md5sum [文件...]

常用参数

参数 说明
-c 校验文件 根据校验文件里的记录逐个核对
--tag 输出 BSD 风格的校验串

示例与预期输出

算一个文件的 MD5 值:

复制代码
md5sum logo.png

预期输出:

复制代码
9a7b1c3d5e7f9a1b2c4d6e8f0a1b3c5d  logo.png

左边是 32 位十六进制哈希,右边是文件名。这个哈希值可以理解成文件的"指纹"------文件内容动一个字节,哈希值就全变了。

生成校验清单并核对:

复制代码
md5sum *.png > MD5SUMS
md5sum -c MD5SUMS

预期输出:

复制代码
logo.png: OK
icon.png: OK

如果中途有人改了某个文件,对应的那行会显示 FAILED。下载发行版镜像时,官网给的 SHA256SUMS 文件就是这个用法。

⚠️ 用途边界

MD5 设计上不是为了防篡改,是为了快速发现意外损坏 (下载中断、磁盘坏道、传输丢包)。它算得快,但抗碰撞能力早就被攻破,别拿它做安全签名。需要防故意篡改的场景用 sha256sum:

复制代码
sha256sum logo.png

输出的哈希串更长(64 位),算法也更可靠。日常校验完整性,sha256sum 是现在的默认选择,md5sum 留着兼容老脚本就行。

五、知识扩展:MD5 与 SHA 家族的区别

MD5、SHA-1、SHA-256、SHA-512 都是哈希算法,把任意长度的输入映射成固定长度的摘要。区别在摘要长度和抗碰撞强度:

算法 摘要长度 现状
MD5 128 位(32 hex) 已被攻破,不用于安全场景
SHA-1 160 位(40 hex) 2017 年实际碰撞,逐步淘汰
SHA-256 256 位(64 hex) 目前行业主流,安全可靠
SHA-512 512 位(128 hex) 更安全,计算略慢

为什么哈希被"碰撞"就算失效?因为攻击者能人为构造出两个不同内容、哈希值相同的文件。一旦这种文件存在,"哈希一致 = 文件没被改"的假设就崩了。下载 CentOS 镜像时官网给的是 sha256sum 文件而不是 md5sum,就是这个原因。

日常写脚本做完整性自检,sha256sum 替换 md5sum 几乎没有迁移成本,参数和用法一模一样。

相关推荐
重生之小比特1 小时前
【Linux系统】06 进程概念
linux
RoboWizard1 小时前
搭配W790芯片组的超频服务器内存(架构选型)FAQ合集
运维·服务器·架构
2402_882893861 小时前
Linux 进程概念详解(上)—— 从冯诺依曼体系到僵尸进程与孤儿进程
linux·运维·服务器
qetfw1 小时前
Debian iptables 防火墙:默认拒绝、SNAT 与 DNAT 验证
linux·服务器·debian·php
格物致胜工业数智技术1 小时前
皮尔磁纸板进料安全方案运维实录:O300传感器用了三年的个人体会
运维·安全
夜之眷属1 小时前
服务启动即崩:InetAddress.getLocalHost() 抛 UnknownHostException 排查记
java·运维·后端·docker
可涵不会debug2 小时前
实测ToDesk新终端:跨端会话恢复+多终端并行,远程Vibe Coding的完整体验报告
运维·电脑
忆挽篱笙歌2 小时前
冯诺依曼+操作系统+进程
linux·ubuntu
xixiaoyunya2 小时前
实验室检测数据内网自动化备份方案:满足合规可追溯的落地实践
服务器·网络·自动化