
1.程序using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace Hex2Bin { class Program { static void Main(string[] args) { if (args.Length 2 || args.Length 3) { ShowHelp(); return; } string inputFile args[0]; string outputFile args[1]; long startOffset 0; long endOffset long.MaxValue; // 处理可选的偏移参数 if (args.Length 3) { if (!long.TryParse(args[2], System.Globalization.NumberStyles.HexNumber, null, out startOffset)) { Console.WriteLine(错误无效的偏移地址格式); return; } endOffset long.MaxValue; } try { ConvertHexToBin(inputFile, outputFile, startOffset, endOffset); Console.WriteLine($转换成功输出文件{outputFile}); } catch (Exception ex) { Console.WriteLine($错误{ex.Message}); } } static void ShowHelp() { Console.WriteLine(Hex2Bin - Intel HEX 转 BIN 格式转换工具); Console.WriteLine(用法Hex2Bin 输入文件.hex 输出文件.bin [起始偏移地址]); Console.WriteLine(示例); Console.WriteLine( Hex2Bin firmware.hex firmware.bin); Console.WriteLine( Hex2Bin firmware.hex firmware.bin 1000 // 从0x1000开始提取); } static void ConvertHexToBin(string hexFile, string binFile, long startOffset, long endOffset) { var dataSegments new Dictionarylong, byte(); long minAddr long.MaxValue; long maxAddr long.MinValue; long currentSegmentAddr 0; long extendedLinearAddr 0; long extendedSegmentAddr 0; string[] lines File.ReadAllLines(hexFile); foreach (string line in lines) { if (string.IsNullOrWhiteSpace(line) || line[0] ! :) continue; // 解析HEX行 byte byteCount Convert.ToByte(line.Substring(1, 2), 16); ushort address Convert.ToUInt16(line.Substring(3, 4), 16); byte recordType Convert.ToByte(line.Substring(7, 2), 16); string dataString line.Substring(9, byteCount * 2); byte checksum Convert.ToByte(line.Substring(9 byteCount * 2, 2), 16); // 验证校验和 byte calcChecksum 0; calcChecksum byteCount; calcChecksum (byte)(address 8); calcChecksum (byte)(address 0xFF); calcChecksum recordType; for (int i 0; i byteCount; i) { calcChecksum Convert.ToByte(dataString.Substring(i * 2, 2), 16); } calcChecksum (byte)((~calcChecksum 1) 0xFF); if (calcChecksum ! checksum) { throw new Exception($校验和错误行 {line}); } // 计算实际地址 long actualAddress; switch (recordType) { case 0x00: // 数据记录 actualAddress extendedLinearAddr address; if (extendedSegmentAddr ! 0) actualAddress (extendedSegmentAddr 4) address; // 存储数据 for (int i 0; i byteCount; i) { byte data Convert.ToByte(dataString.Substring(i * 2, 2), 16); long addr actualAddress i; if (addr startOffset addr endOffset) { if (!dataSegments.ContainsKey(addr)) dataSegments[addr] data; if (addr minAddr) minAddr addr; if (addr maxAddr) maxAddr addr; } } break; case 0x01: // EOF break; case 0x02: // 扩展段地址 extendedSegmentAddr Convert.ToUInt16(dataString, 16); break; case 0x03: // 起始段地址 // 忽略 break; case 0x04: // 扩展线性地址 extendedLinearAddr Convert.ToUInt32(dataString, 16) 16; extendedSegmentAddr 0; break; case 0x05: // 起始线性地址 // 忽略 break; } } if (dataSegments.Count 0) { throw new Exception(没有找到有效的数据记录); } // 创建连续的数据缓冲区 long totalSize maxAddr - minAddr 1; byte[] binData new byte[totalSize]; // 填充数据 foreach (var kvp in dataSegments) { binData[kvp.Key - minAddr] kvp.Value; } // 写入BIN文件 File.WriteAllBytes(binFile, binData); Console.WriteLine($转换统计); Console.WriteLine($ 起始地址0x{minAddr:X8}); Console.WriteLine($ 结束地址0x{maxAddr:X8}); Console.WriteLine($ 数据大小{totalSize} 字节); } } }2. 使用方法# 基本用法 Hex2Bin.exe input.hex output.bin # 指定起始地址十六进制 Hex2Bin.exe input.hex output.bin 1000 # 显示帮助 Hex2Bin.exe3.程序特点支持标准Intel HEX格式数据记录00文件结束记录01扩展段地址02扩展线性地址04起始地址记录03, 05校验和验证每行HEX数据都会验证校验和地址范围过滤可选的起始地址参数内存高效使用字典存储非连续数据段4.使用示例假设有HEX文件内容:100000000102030405060708090A0B0C0D0E0F101A :100010001112131415161718191A1B1C1D1E1F2029 :00000001FF转换后的BIN文件将包含地址0x0000-0x001F的32字节数据。这个工具适用于嵌入式开发中常见的固件格式转换需求。