在 JavaScript 中将大整数转换为 8 字节数组
Converting large integer to 8 byte array in JavaScript
我正在尝试在javascript中将一个大数字转换为8字节数组。
这是我传入的IMEI:45035997012373300
var bytes = new Array(7);
for(var k=0;k<8;k++) {
bytes[k] = value & (255);
value = value / 256;
}
这最终给出了字节数组:48,47,7,44,0,0,160,0。换算回 long,该值为 45035997012373296,比正确值小 4
。知道为什么会这样以及如何修复它以序列化为正确的字节吗?
由于您要从十进制转换为字节,因此除以 256 是一种通过将字符串中的数字拆分为部分来轻松模拟的操作。 我们可以利用两个数学规则。
- 十进制数最右边的 n 位数字可以确定 2^n 的整除性。
- 10^n 将始终能被 2^n 整除。
因此,我们可以取数字并拆分最右边的 8 位数字以找到余数(即 & 255
),将右侧部分除以 256,然后将数字的左侧部分分别除以 256。 左边的余数可以通过公式n*10^8 ' 256 = (q*256+r)*10^8 ' 256 = q*256*10^8'256 + r*10^8'256 = q*10^8 + r*5^8
移动到数字的右部(最右边的8位数字),其中'
是整数除法,q
和r
分别是商和余数,对于n ' 256
。 这将产生以下方法,对于长度最多为 23 位(此方法产生 15 个正常 JS 精度 + 8 个额外产生的)的字符串进行整数除以 256:
function divide256(n)
{
if (n.length <= 8)
{
return (Math.floor(parseInt(n) / 256)).toString();
}
else
{
var top = n.substring(0, n.length - 8);
var bottom = n.substring(n.length - 8);
var topVal = Math.floor(parseInt(top) / 256);
var bottomVal = Math.floor(parseInt(bottom) / 256);
var rem = (100000000 / 256) * (parseInt(top) % 256);
bottomVal += rem;
topVal += Math.floor(bottomVal / 100000000); // shift back possible carry
bottomVal %= 100000000;
if (topVal == 0) return bottomVal.toString();
else return topVal.toString() + bottomVal.toString();
}
}
从技术上讲,这可以实现为将任意大小的整数除以 256,只需递归地将数字分成 8 位数字并使用相同的方法分别处理每个部分的除法即可。
这是一个有效的实现,它为您的示例数字 ( 45035997012373300
) 计算正确的字节数组 : http://jsfiddle.net/kkX2U/.
[52, 47, 7, 44, 0, 0, 160, 0]
您的值和最大的 JavaScript 整数比较:
45035997012373300 // Yours
9007199254740992 // JavaScript's biggest integer
JavaScript 不能将你的原始值完全表示为整数;这就是为什么你的脚本分解它会给你一个不精确的表示。
相关:
var diff = 45035997012373300 - 45035997012373298;
// 0 (not 2)
编辑:如果您可以将数字表示为十六进制字符串:
function bytesFromHex(str,pad){
if (str.length%2) str="0"+str;
var bytes = str.match(/../g).map(function(s){
return parseInt(s,16);
});
if (pad) for (var i=bytes.length;i<pad;++i) bytes.unshift(0);
return bytes;
}
var imei = "a000002c072f34";
var bytes = bytesFromHex(imei,8);
// [0,160,0,0,44,7,47,52]
如果需要按最低到最重要排序的字节,请对结果进行.reverse()
。
imei 存储为十六进制字符串(如果可以),然后以这种方式解析字符串,这样您就可以在构建数组时保持精度。如果我回到家时,我会带着 PoC 回到我的普通电脑上,如果这个问题没有得到回答。
像这样:
function parseHexString(str){
for (var i=0, j=0; i<str.length; i+=2, j++){
array[j] = parseInt("0x"+str.substr(i, 2));
}
}
或者接近那个...
- 本地存储中的字符串到字节数组转换
- Javascript替换字节数组序列
- 如何在Javascript中存储字节数组
- JavaScript代码,用于在浏览器中显示字节数组中的PDF文件(非base64编码)
- 正在从字节数组加载图像内容
- Javascript + ActionScript:如何将从Actionscript返回的字节数组转换为Javascri
- 将十六进制字符串转换为字节数组
- 在javascript中将声音转换为字节数组
- 在 MVC3 中将字节数组显示为图像
- 如何在ASP.NET Response.BinaryWrite生成的Javascript中处理字节数组映像
- 在javascript中将字节数组转换为有符号的int64
- 如何使用Node.js将字节数组转换为字符串
- Yodlee获取Captcha的MFAR响应字节数组
- 使用PDF.JS和AngularJS从字节数组渲染PDF
- 如何在javascript中将字节数组转换为字符串
- 将字节数组保存到Titanium中的pdf文件中
- Node js从web获取图像并将其转换为字节值数组
- 如何读取二进制文件字节字节使用javascript
- 如何将多字节字符串数组转换为32位整型数组
- 如何将Javascript字符串转换为八位字节/字符数组