Linux下C/C++实现以十六进制的形式显示命令(xxd)

本文详细介绍了Linux下xxd命令的使用方法,包括如何创建十六进制转储、编辑二进制文件等,并提供了多种实用示例。同时,还展示了xxd命令的C/C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果你需要在linux文本文件的十六进制转储?且正在寻找可以执行此操作的命令行实用程序,xxd的命令可以为你做这件事。xxd命令将文件显示为十六进制值和ASCII表示,并允许对其进行编辑。

xxd - 以十六进制形式表示

xxd程序接受文件或标准输入,并输出仅使用ASCII或EBCDIC字符的十六进制转储。这个输出十六进制转储可以安全地通过电子邮件发送并在目的地重建。它还可以采用格式相同的十六进制转储并将其转换回二进制格式,从而允许二进制文件作为文本进行编辑或修补。

语法:

以下是xxd命令的一般语法。请注意,如果参数包含在长选项名称(如-autoskip)中,则可以使用相应的短选项(如-a)指定相同的参数。
显示命令帮助或版本:

xxd -h[elp]

创建十六进制转储:

xxd [options] [infile [outfile]]

将十六进制转储转换为二进制:

xxd -r[evert] [options] [infile [outfile]]

选项如下:

如何使用xxd命令?

以下示例显示了可以使用xxd的一些方式。通过在命令提示符中键入man-xxd,请参阅xxd手册页以获取更多示例。

下面是如何使用xxd将文件内容转换为十六进制:

如何打印文件的前20个字节

上面的三个命令都读取test.txt的内容,获取前20个字节,并将其打印为十六进制转储。第一个命令指定十进制长度(20),第二个命令指定十六进制长度(0x14),第三个命令指定八进制长度(024)。

如何打印文件的最后20个字节

上面的三个命令都读取test.txt的内容,转到文件的末尾,向后搜索(-符号)20个字节,然后作为十六进制转储向前打印。第一个命令指定十进制长度(20),第二个命令指定十六进制长度(0x14),第三个命令指定八进制长度(024)。

如何将文件的前20个字节打印为位


上面的命令读取test.txt的内容,获取前20个字节,并将其打印为二进制转储.

如何将120个字节打印为连续十六进制转储,每行20个八位字节

如何编辑二进制文件

xxd手册页有一行编辑步骤。为了清晰起见,本示例分解了步骤。将文件转换为十六进制转储。

上面的命令读取test.txt的内容,将其转换为十六进制转储,并将其写入hexd_file.txt。

将十六进制转储转换回二进制

在这里插入图片描述

上面的命令读取hex_file.txt的内容,将其还原为二进制形式,并将其写入binary_file.txt。

如何创建文本文件

上面的命令打印通过管道发送到xxd命令的十六进制值。-r返回,-p表示纯十六进制,没有给出行信息。这将从打印重定向到屏幕,并保存为test_file.txt。如果不包含>test_file.txt,则将结果打印到stdout。

在这里插入图片描述

Linux下C/C++实现xxd命令

...
static void xxdline(FILE *fp, char *l, int nz)
{
	static char z[LLEN+1];
	static int zero_seen = 0;

	if (!nz && zero_seen == 1)
		strcpy(z, l);

	if (nz || !zero_seen++)
	{
		if (nz)
		{
		  if (nz < 0)
			zero_seen--;
		  if (zero_seen == 2)
			  if (fputs(z, fp) == EOF)
				 die(3);
		  if (zero_seen > 2)
			  if (fputs("*\n", fp) == EOF)
			     die(3);
		}
		if (nz >= 0 || zero_seen > 0)
			if (fputs(l, fp) == EOF)
				die(3);
			if (nz)
				zero_seen = 0;
	}
}
...
int main(int argc, char *argv[])
{

...

	pname = argv[0];
	for (pp = pname; *pp; )
		if (*pp++ == PATH_SEP)
			pname = pp;

	while (argc >= 2)
    {
		pp = argv[1] + (!STRNCMP(argv[1], "--", 2) && argv[1][2]);
		if (!STRNCMP(pp, "-a", 2)) autoskip = 1 - autoskip;
		else if (!STRNCMP(pp, "-b", 2)) hextype = HEX_BITS;
		else if (!STRNCMP(pp, "-e", 2)) hextype = HEX_LITTLEENDIAN;
		else if (!STRNCMP(pp, "-u", 2)) hexx = hexxa + 16;
		else if (!STRNCMP(pp, "-p", 2)) hextype = HEX_POSTSCRIPT;
		else if (!STRNCMP(pp, "-i", 2)) hextype = HEX_CINCLUDE;
		else if (!STRNCMP(pp, "-r", 2)) revert++;
		else if (!STRNCMP(pp, "-E", 2)) ebcdic++;
		else if (!STRNCMP(pp, "-v", 2))
		{
			fprintf(stderr, "%s%s\n", version, osver);
			exit(0);
		}
		else if (!STRNCMP(pp, "-c", 2))
		{
			if (pp[2] && STRNCMP("ols", pp + 2, 3))
				cols = (int)strtol(pp + 2, NULL, 0);
			else
			{
			  if (!argv[2])
			  exit_with_usage();
			  cols = (int)strtol(argv[2], NULL, 0);
			  argv++;
			  argc--;
			}
		}
		else if (!STRNCMP(pp, "-g", 2))
		{
			if (pp[2] && STRNCMP("group", pp + 2, 5))
				octspergrp = (int)strtol(pp + 2, NULL, 0);
			else
			{
			  if (!argv[2])
			  exit_with_usage();
			  octspergrp = (int)strtol(argv[2], NULL, 0);
			  argv++;
			  argc--;
			}
		}
		else if (!STRNCMP(pp, "-o", 2))
		{
			if (pp[2] && STRNCMP("ffset", pp + 2, 5))
				displayoff = (int)strtol(pp + 2, NULL, 0);
		else
		{
			if (!argv[2])
			  exit_with_usage();
			displayoff = (int)strtol(argv[2], NULL, 0);
			argv++;
			argc--;
		}
		}
		else if (!STRNCMP(pp, "-s", 2))
		{
			relseek = 0;
			negseek = 0;
			if (pp[2] && STRNCMP("kip", pp+2, 3) && STRNCMP("eek", pp+2, 3))
			{
				seekoff = strtol(pp + 2+relseek+negseek, (char **)NULL, 0);
			}
			else
			{
			  if (!argv[2])
				exit_with_usage();
			  seekoff = strtol(argv[2] + relseek+negseek, (char **)NULL, 0);
			  argv++;
			  argc--;
			}
		}
		else if (!STRNCMP(pp, "-l", 2))
		{
			if (pp[2] && STRNCMP("en", pp + 2, 2))
				length = strtol(pp + 2, (char **)NULL, 0);
			else
			{
			  if (!argv[2])
				 exit_with_usage();
			  length = strtol(argv[2], (char **)NULL, 0);
			  argv++;
			  argc--;
			}
		}
		else if (!strcmp(pp, "--"))	/* end of options */
		{
			argv++;
			argc--;
			break;
		}
		else if (pp[0] == '-' && pp[1])	/* unknown option */
			exit_with_usage();
		else
			break;				/* not an option */

		argv++;				/* advance to next argument */
		argc--;
    }

	if (!cols)
		switch (hextype)
		{
			case HEX_POSTSCRIPT:	cols = 30; break;
			case HEX_CINCLUDE:	cols = 12; break;
			case HEX_BITS:		cols = 6; break;
			case HEX_NORMAL:
			case HEX_LITTLEENDIAN:
			default:			cols = 16; break;
		}

	if (octspergrp < 0)
		switch (hextype)
		{
			case HEX_BITS:		octspergrp = 1; break;
			case HEX_NORMAL:		octspergrp = 2; break;
			case HEX_LITTLEENDIAN:	octspergrp = 4; break;
			case HEX_POSTSCRIPT:
			case HEX_CINCLUDE:
			default:			octspergrp = 0; break;
		}

	if (cols < 1 || ((hextype == HEX_NORMAL || hextype == HEX_BITS || hextype == HEX_LITTLEENDIAN)
								&& (cols > COLS)))
	{
		  fprintf(stderr, "%s: invalid number of columns (max. %d).\n", pname, COLS);
		  exit(1);
	}
...
	
}	


If you need the complete source code of xxd, add your WeChat number (c17865354792)

总结

xxd创建给定文件或标准输入的十六进制转储。它还可以将十六进制转储转换回其原始二进制形式,因此,如果处理十六进制和二进制文件内容,xxd命令非常有用。

Welcome to follow WeChat official account【程序猿编码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值