【问题标题】:How to split large integer into an array of 8-bit integers如何将大整数拆分为 8 位整数数组
【发布时间】:2018-11-20 22:30:34
【问题描述】:

想知道如何将任意大小的整数(如1123455324617851000199519157)的输出转换为整数数组。

[1] // for the first one
// [probably just a few values for the second 12345...]
[1, 123, 255, 32, ...] // not sure here...

我不确定结果值会是什么样子或如何计算它,但不知何故它会是这样的:

一组 8 位数字,可用于(以某种方式)重构原始任意整数。我也不确定要执行此操作需要进行哪些计算。但我所知道的是,每个唯一的任意大小的整数都应该产生一个唯一的 8 位值数组。也就是说,任何两个不同的日期整数都不应该产生相同的数组。

语言如何实现并不重要,但可能是一种命令式语言,如 JavaScript 或 C。

我很确定数组的长度也应该相同,但如果这不可能,那么知道如何以不同的方式来做就可以了。

【问题讨论】:

  • 为什么不直接获取年、月、日等组件呢?
  • 为什么不使用带有 time() 和 localtime() 的时间戳来获取时间及其组件?
  • 对不起,日期让我感到困惑,日期部分无关紧要。
  • 您实际上想完成什么?您可以轻松地将一个 n 位整数拆分为 n/8 个 8 位整数,然后重构原始整数……但如果您实际上是在寻找一种更有效的时间封装方式,那将毫无意义。
  • 与日期/日期时间无关,对此感到抱歉。更新了问题。我想将任意大小的任何整数转换为 8 位整数数组。

标签: javascript c integer


【解决方案1】:

我不确定这对于您想要的是否过于暴力,但您可以使用任意字符串并将长除法转换为 unit8Array

这是一个函数(大量借用自 here),它将从任意长的字符串来回转换:

function eightBit(str){ 
    let dec = [...str],  sum = []
    while(dec.length){
        let s = 1 * dec.shift()
        for(let i = 0; s || i < sum.length; i++){
            s += (sum[i] || 0) * 10
            sum[i] = s % 256
            s = (s - sum[i]) / 256
        }
    } 
    return Uint8Array.from(sum.reverse())
}


function eightBit2String(arr){ 
    var dec = [...arr], sum = []
    while(dec.length){
        let s = 1 * dec.shift()
        for(let i = 0; s || i < sum.length; i++){
            s += (sum[i] || 0) * 256
            sum[i] = s % 10
            s = (s - sum[i]) / 10
        }
    }
    return sum.reverse().join('')
}

// sanity check
console.log("256 = ", eightBit('256'), "258 = ", eightBit('258')) 
 
let n = '47171857151875817758571875815815782572758275672576575677'
let a = eightBit(n)
console.log("to convert:", n)
console.log("converted:", a.toString())
let s = eightBit2String(a)
console.log("converted back:", s)

毫无疑问,可以找到一些效率(也许您可以避免使用临时数组)。

【讨论】:

  • 想知道每个唯一输入的输出是否都是唯一的。也就是说,不会有碰撞。
  • 如果字符串中有零,这会失败,知道如何解决吗?就像在 1024 上一样。
  • @LancePollard 当我运行eightBit('1024') 时,它会按预期生成[4, 0]。转换回 eightBit2String([4, 0]) 也会得到预期的 1024。我的期望是错误的吗(这是一个很老的问题——有一段时间没有考虑过这个问题)?
  • 哦,好吧,我认为你是对的,我正在向后处理它,好吧,很高兴知道,谢谢!
【解决方案2】:

大多数语言(包括 C 和 Javascript)都将位移位和位掩码操作作为其基本数学运算的一部分。但要注意 Javascript:数字是 64 位的,但只允许 32 位屏蔽操作。所以:

let bignum = Date.now();
let hi = Math.floor(bignum / 0x100000000),
    lo = bignum & 0xFFFFFFFF,
    bytes = [
        (hi >> 24) & 0xFF,
        (hi >> 16) & 0xFF,
        (hi >> 8) & 0xFF,
        hi & 0xFF,
        (lo >> 24) & 0xFF,
        (lo >> 16) & 0xFF,
        (lo >> 8) & 0xFF,
        lo & 0xFF
    ];

【讨论】:

  • 如果整数是一个字符串并且它是一个任意大小的“bigint”,我认为这不会起作用。我想让它处理这个问题,不知道你怎么知道bytes 数组中有 8 个项目,这可能不适用于从 0'47171857151875817758571875815815782572758275672576575677' 或任意大小的任意大小的小/大整数大小。
  • 这对你来说可能看起来比较简单,但我不明白Math.floor(bignum / 0x100000000) 来自哪里?
  • @zfrisch 将高 32 位移至低 32 位。 Javascript >> 32 只会产生一个 0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-28
  • 2010-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-19
  • 2014-12-06
相关资源
最近更新 更多