我需要通过NetworkStream发送一个整数。问题是我只能发送字节。 这就是为什么我需要将整数分成四个字节并发送,然后在另一端将其转换回int。
现在我只需要在C#中使用它。但是对于最终的项目,我需要将四个字节转换为Lua中的int。
[编辑] 在Lua怎么样?
答案 0 :(得分:9)
BitConverter是最简单的方法,但是如果你想控制字节的顺序,你可以自己进行位移。
int foo = int.MaxValue;
byte lolo = (byte)(foo & 0xff);
byte hilo = (byte)((foo >> 8) & 0xff);
byte lohi = (byte)((foo >> 16) & 0xff);
byte hihi = (byte)(foo >> 24);
此外..BitConverter的实现使用不安全和指针,但它简短而简单。
public static unsafe byte[] GetBytes(int value)
{
byte[] buffer = new byte[4];
fixed (byte* numRef = buffer)
{
*((int*) numRef) = value;
}
return buffer;
}
答案 1 :(得分:6)
尝试
BitConverter.GetBytes()
http://msdn.microsoft.com/en-us/library/system.bitconverter.aspx
请记住,返回数组中字节的顺序取决于系统的字节顺序。
编辑: 至于Lua部分,我不知道如何转换回来。您总是可以乘以16来获得与按位移位相同的功能。它不是很漂亮,我会想象有一些库或某些东西可以实现它。同样,添加字节的顺序取决于字节顺序,因此您可能希望阅读
也许你可以用C#转换回来?
答案 2 :(得分:2)
以下是 Lua 中的一些函数,用于将32位二进制补码数转换为字节,并将四个字节转换为32位二进制补码数。可以/应该进行更多检查以验证传入参数是否有效。
-- convert a 32-bit two's complement integer into a four bytes (network order)
function int_to_bytes(n)
if n > 2147483647 then error(n.." is too large",2) end
if n < -2147483648 then error(n.." is too small",2) end
-- adjust for 2's complement
n = (n < 0) and (4294967296 + n) or n
return (math.modf(n/16777216))%256, (math.modf(n/65536))%256, (math.modf(n/256))%256, n%256
end
-- convert bytes (network order) to a 32-bit two's complement integer
function bytes_to_int(b1, b2, b3, b4)
if not b4 then error("need four bytes to convert to int",2) end
local n = b1*16777216 + b2*65536 + b3*256 + b4
n = (n > 2147483647) and (n - 4294967296) or n
return n
end
print(int_to_bytes(256)) --> 0 0 1 0
print(int_to_bytes(-10)) --> 255 255 255 246
print(bytes_to_int(255,255,255,246)) --> -10
答案 3 :(得分:2)
对于Lua,请查看Roberto的struct图书馆。 (罗伯托是Lua的作者之一。)对于具体案例来说,它比一般情况更为笼统,但是不一定需要交换int
之后需要交换其他案例。简单类型或更大的结构。
假设本端字节顺序在两端都是可接受的(这可能是一个错误的假设,偶然),那么你可以将数字转换为4字节整数:
buffer = struct.pack("l", value)
然后再回来:
value = struct.unpack(“l”,buffer)
在这两种情况下,buffer
都是包含字节的Lua字符串。如果您需要从Lua访问单个字节值,string.byte
是您的朋友。
要指定打包数据的字节顺序,请将格式从"l"
更改为"<l"
(对于little-endian)或">l"
(对于big-endian)。
struct
模块在C中实现,在Lua可以使用之前,必须将其编译为您的平台的DLL或等效模块。也就是说,它包含在Lua for Windows电池包含的安装包中,这是在Windows系统上安装Lua的常用方法。
答案 4 :(得分:1)
调查BinaryWriter / BinaryReader类
答案 5 :(得分:1)
将int转换为字节数组并显示:BitConverter ...
www.java2s.com/Tutorial/CSharp/0280__Development/Convertaninttoabytearrayanddisplay.htm
整数到字节 - Visual Basic .NET回答
http://bytes.com/topic/visual-basic-net/answers/349731-integer-byte
如何:将字节数组转换为int(C#编程指南)
答案 6 :(得分:1)
正如Nubsis所说,BitConverter
是合适的,但没有保证的字节顺序。
我在MiscUtil中有一个EndianBitConverter
类,允许您指定字节序。当然,如果您只想对单个数据类型(int
)执行此操作,则可以手动编写代码。
BinaryWriter
是另一种选择,而 保证少量字节序。 (再次,如果你想要其他选项,MiscUtil有一个EndianBinaryWriter
。)
答案 7 :(得分:1)
转换为字节[]:
BitConverter.GetBytes(int)的
http://msdn.microsoft.com/en-us/library/system.bitconverter.aspx
要转换回int:
BitConverter.ToInt32(byteArray,offset)
http://msdn.microsoft.com/en-us/library/system.bitconverter.toint32.aspx
我不确定Lua。
如果您担心字节顺序,请使用John Skeet的EndianBitConverter。我已经使用它了,它可以无缝地工作。
C#支持自己实现htons和ntohs:
但是它们只能在signed int16,int32,int64上工作,这意味着你可能最终会进行大量不必要的转换以使它们工作,并且如果你使用最高位除了签署整数以外的任何东西, 你完蛋了。去过也做过。 :: tsk ::: tsk :: Microsoft因为没有在.NET中提供更好的字节顺序转换支持。