字节数组转十六进制字符串的字节序问题及测试失效场景咨询
问题解答
1. 单元测试是否存在运行失败场景?
确实存在会运行失败的场景,而且只有一个:
- 当测试跑在**.NET 5 以下版本**上(包括.NET Core 3.1、所有版本的.NET Framework),会因为
Convert类没有ToHexString方法直接抛MissingMethodException,测试直接失败。
只要框架版本符合要求、传入的字节数组不是null,测试逻辑本身没有其他会触发断言报错的问题。
2. 大端架构机器上运行该测试是否会失败?
只要框架版本满足要求,在大端机器上跑也不会失败。
原因很简单,三个用来做对比的方法,逻辑上完全不依赖CPU的字节序:
- 测试里的字节数组是代码硬编码写死的,索引0到3固定是16、171、205、239四个值,不管CPU是大端还是小端,数组元素的顺序都不会变。
- 不管是自定义的
ByteArrayToHexString,还是BitConverter.ToString、Convert.ToHexString,内部逻辑都是老老实实按数组索引从低到高遍历,每个字节先取高4位转十六进制、再取低4位转十六进制,拼到结果里,全程根本不会判断当前系统是大端还是小端,也不会调整字节顺序,相同输入不管在什么架构下跑输出都一模一样。
这里有个很常见的误区:很多人以为所有
BitConverter的方法都和字节序有关,实际上只有多字节类型和字节数组互转的方法(比如GetBytes(int)、ToInt32(byte[]))会受系统字节序影响,BitConverter.ToString(byte[])只是单纯把每个字节转成十六进制字符串,和字节序没有关系。
3. ByteArrayToHexString是否为小端实现?
这个方法既不是小端实现,也不是大端实现。
它本身根本没写任何字节序相关的处理逻辑,就是你传什么顺序的字节数组,它就按什么顺序拼字符串:
- 要是你传的数组是按大端规则存的多字节值(高位字节放在数组前面的低索引位置,和人写数字的顺序一致),拼出来的就是符合大端阅读习惯的字符串;
- 要是你传的数组是按小端规则存的多字节值(低位字节放在数组前面),拼出来的就是小端格式的字符串。
方法本身不会主动调整字节顺序,和运行环境原生用大端还是小端也没有任何关系。
4. 为什么从左到右写入字符的逻辑看起来像大端实现?
因为大端的规则本身就和人从左到右读写的习惯是对齐的。
大端的核心就是「高位在前」,和我们平时写数字,先写高位、再写低位,从左往右排的习惯完全一样。你按数组顺序从左往右拼字符的时候,只要数组里高位字节排在前面,出来的字符串自然就是高位在左、低位在右,刚好符合大家对大端格式的直观印象。
很多人会搞混这个方法的字节序属性,本质上是把「方法本身的逻辑」和「传入数据的排列规则」搞混了:如果你在小端机器上用BitConverter.GetBytes()拿一个整数的字节数组(这时候低位字节会排在数组前面),传给这个方法拼出来的字符串就是低位在左、高位在右,看起来是小端格式,但这是你传进去的数组本身顺序就是小端的,不是这个方法做了什么小端转换。
内容的提问来源于stack exchange,提问作者Alexander Kozachenko
相关产品推荐
相关产品推荐

