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 几乎没有迁移成本,参数和用法一模一样。

相关推荐
志栋智能8 小时前
运维超自动化的版本控制与回滚机制
运维·自动化
中云DDoS CC防护蔡蔡8 小时前
DDOS和CC攻击谁更可怕
运维·服务器·经验分享·网络安全·ddos
Ruiery8 小时前
Linux 6.6内核内存管理深度解析(十六):mmap — 用户态“申请内存“的真相
linux·运维·服务器
ClickHouseDB8 小时前
ClickHouse Cloud 与 Snowflake 实时性价比对比:CostBench 测试中的 412 倍差距来
运维·数据库·系统架构
欧米欧9 小时前
Linux系统篇(七),环境变量的底层溯源,核心获取机制与安全应用
linux·运维·服务器
Ruiery9 小时前
Linux 6.6内核内存管理深度解析(十八):KASLR 内核地址空间随机化
linux·运维·服务器·安全
todoitbo9 小时前
群晖NAS部署JmalCloud:Docker安装、文件管理、博客与公网访问完整教程
运维·docker·容器
时间售卖铺9 小时前
触发器与函数实战:MySQL高效编程秘诀
运维·数据库·mysql·云原生
qetfw10 小时前
UOS MariaDB 数据库:安装、最小权限与备份验证
linux·数据库·mariadb·uos
前端精髓10 小时前
调用大模型API
运维·服务器·microsoft