int 与 byte[] 的相互转换

博客介绍了int与byte[]相互转换的四种方法,包括最普通的位运算方法、使用BitConverter类的方法、Unsafe代码方法,还提及将结构类型转换成byte[]时第四种方法较方便,每种方法都给出了示例代码。

    关于 int 与 byte[] 的相互转换,Mattias Sjogren 介绍了3种方法。请参见 《将Integer转换成Byte Array》。其实应该还有不少方法。在这里,我归纳了包括Mattias Sjogren在内的4种方法。

1. 最普通的方法

  • 从byte[] 到 uint
    b = new byte[] {0xfe,0x5a,0x11,0xfa};
    u = (uint)(b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24);
  • 从int 到 byte[]
    b[0] = (byte)(u);
    b[1] = (byte)(u >> 8);
    b[2] = (byte)(u >> 16);
    b[3] = (byte)(u >> 24);

2. 使用 BitConverter (强力推荐)

  • 从int 到byte[]
    byte[] b = BitConverter.GetBytes(
       0xba5eba11 );
    //{0x11,0xba,0x5e,0xba}
  • 从byte[]到int
    uint u = BitConverter.ToUInt32(
       new byte[] {0xfe, 0x5a, 0x11,
       0xfa},0 ); // 0xfa115afe

3. Unsafe代码 (虽然简单,但需要更改编译选项)

unsafe {
// 从int 到byte[]
fixed ( byte* pb = b ) 
// 从byte[] 到 int








u = *((uint*)pb);
}
4. 使用Marshal类

    IntPtr ptr = Marshal.AllocHGlobal(4); // 要分配非托管内存
    byte[] b= new byte[4]{1,2,3,4};
//从byte[] 到 int
    Marshal.Copy(b, 0, ptr, 4);
    int u = Marshal.ReadInt32(ptr);
//从int 到byte[]
    Marshal.WriteInt32(ptr, u);
    Marshal.Copy(ptr,b,0,4);
    Marshal.FreeHGlobal(ptr); // 最后要记得释放内存

    使用第4种看起来比较麻烦,实际上,如果想把结构(struct)类型转换成byte[],则第4种是相当方便的。例如:

    int len = Marshal.Sizeof(typeof(MyStruct));
    MyStruct o;
    byte[] arr = new byte[len];//{...};

    IntPtr ptr = Marshal.AllocHGlobal(len);
    try
    {
// 从byte[] 到struct MyStruct
     Marshal.Copy(arr, index, ptr, Math.Min(length, arr.Length - index));
     o = (MyStruct)Marshal.PtrToStructure(ptr, typeof(MyStruct));


// 从struct MyStruct 到 byte[]
     Marshal.StructureToPtr(o, ptr, true); // 使用时要注意fDeleteOld参数
     Marshal.Copy(ptr, arr, 0, len);
    }
    finally
    {
     Marshal.FreeHGlobal(ptr);
    }
    return o;

<think>嗯,用户需要了解byte、char、int、hex之间的相互转换方法,还提供了四个参考资料。这些引用内容涉及C/C++和Java的实现,正好可以覆盖主流编程场景。 用户可能正在处理底层数据传输或协议解析,需要精确控制数据类型转换。从引用[1][2]看,用户关注的是C语言和字节数组操作,而引用[3][4]展示了Java和C++的十六进制处理。这说明用户需要跨语言的解决方案。 注意到引用中几个关键点:引用[2]强调无符号转换时要用&0xff防止符号扩展,引用[3]展示了Java的十六进制格式化技巧,引用[4]则是C++的sprintf实现。这些细节在回答时需要重点说明。 考虑到用户引用资料较零散,准备整理成表格形式会更清晰。数据类型转换容易踩坑,比如char的符号问题和字节序问题,这些实践中容易出错的地方需要特别标注。用户没有指定语言,所以决定同时给出C/C++和Java的实现方案。 关于十六进制转换,用户提供的两种方案各有用处:String.format适合Java,sprintf适合C++。性能方面,StringBuilder比字符串拼接更高效,这个优化点值得提及。此外,用户没提但可能需要的字节序问题也补充说明。 最后生成的问题覆盖了实际应用场景(如网络通信)、常见错误和高级话题(字节序),这样能帮助用户深入理解。特别加入"无符号转换"这个问题,因为引用[2]提到&0xff这个易错点,很多开发者会忽略。 </think> 以下是针对 C/C++ 和 Java 的 `byte`、`char`、`int`、`hex` 之间相互转换的常用方法总结,结合了引用内容并补充了关键细节: --- ### **一、核心转换方法** #### 1. **`int` `byte[]` (C/C++)** ```c void intToBytes(int value, byte* bytes) { // 小端序(低位在前) bytes[0] = (value & 0xFF); bytes[1] = ((value >> 8) & 0xFF); bytes[2] = ((value >> 16) & 0xFF); bytes[3] = ((value >> 24) & 0xFF); } ``` > **注意**:`& 0xFF` 确保只取低8位,避免符号扩展问题[^2]。 #### 2. **`byte[]` `int` (C/C++)** ```c int bytesToInt(const byte* bytes) { return (bytes[0] & 0xFF) | ((bytes[1] & 0xFF) << 8) | ((bytes[2] & 0xFF) << 16) | ((bytes[3] & 0xFF) << 24); } ``` #### 3. **`byte[]` 十六进制字符串 (Java)** ```java String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02X", b)); // %02X 保证两位大写十六进制 } return sb.toString(); } ``` > 引用自[^3],`%02X` 中的 `02` 确保单字节补零对齐。 #### 4. **十六进制字符串 `byte[]` (C++)** ```cpp void hexToBytes(const std::string& hexStr, byte* bytes) { for (int i = 0; i < hexStr.length(); i += 2) { std::string byteStr = hexStr.substr(i, 2); bytes[i/2] = static_cast<byte>(std::stoul(byteStr, nullptr, 16)); } } ``` #### 5. **`char` `byte` 转换 (C/C++)** ```c // char byte (无符号) byte charToByte(char c) { return (byte)(c & 0xFF); // 避免符号位扩展 } // byte char char byteToChar(byte b) { return (char)b; // 直接转换(注意符号问题) } ``` --- ### **二、关键注意事项** 1. **符号问题** - Java 的 `byte` 有符号,C/C++ `char` 默认符号取决于编译器。 - 转换时用 `& 0xFF` 确保无符号处理(如 `(byte)0xFE` 在 Java 为 `-2`,`& 0xFF` 后为 `254`)[^2]。 2. **字节序(Endianness)** - `int` `byte[]` 转换需明确大小端(示例为小端序)。 - 网络通信常用大端序(参考 `htonl()`, `ntohl()` 函数)。 3. **十六进制格式** - `%02X` 在 Java 中保证输出两位大写十六进制(如 `0xA` → `"0A"`)[^3]。 - C/C++ 可用 `sprintf(buf, "%02X", byte)` 实现类似效果[^4]。 --- ### **三、完整示例(Java)** ```java // int byte[] byte[] intToBytes(int value) { return new byte[] { (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value }; } // byte[] 十六进制 String hex = bytesToHex(new byte[] {0x48, 0x65, 0x6C}); // 输出 "48656C" ``` ```cpp // C++:十六进制 char[] std::string hexStr = "48656C"; char chars[3]; hexToBytes(hexStr, (byte*)chars); // chars = {'H', 'e', 'l'} ``` --- ### **
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值