我正在编写一个自定义反序列化系统,用于通过网络对数据进行分组,并按以下方式序列化双倍:
private static string EncodeDouble(double raw)
{
long value = BitConverter.DoubleToInt64Bits(raw);
return EncodeInteger(value);
}
EncodeInteger
函数只是将整数转换为标记字符串,因此反序列化代码知道它具有正确的数据类型。
另一方面,我按照以下方式进行反序列化:
private static double DecodeDouble(string raw)
{
long value = DecodeInteger<long>(raw);
return BitConverter.Int64BitsToDouble(value);
}
同样,DecodeInteger
只删除标记并验证该值是否在范围内一段时间,然后转换为long。这是安全的,因为如果出现任何问题,它只会抛出异常。
我担心的原因是,在进入参考源之后,我看到了这种直接不安全的演员:
public static unsafe double Int64BitsToDouble(long value) {
return *((double *)&value);
}
我预见到的问题是,long的值可以被任意修改,因为它正在通过网络。我并不担心任意修改的值,而是如果发送了无效的基础double
表示,CLR可能会遇到问题。
我不确定是否有不映射到有效long
的潜在double
值,但如果有,我可能会看到什么? CLR会崩溃,导致拒绝服务吗?或者是否有可以捕获的异常?
答案 0 :(得分:2)
AFAIK这里没有任何“无效”值;只是不是你原先想到的那些价值观。所以,您在拒绝服务方面没有太多担心。相比之下,注意decimal
可能具有无效的二进制表示 - 这些只会抛出异常而单个调用将失败 - 仍然不是拒绝服务(只是:他们'我会看到失败)。
但是,就个人而言,我建议将double
编码为long
然后编码为string
,这可能是硬件/效率低下的方式。如果您迫切需要它作为string
,请考虑使用base-64编码这些位。