【问题标题】:Flooring a random exponential value for a cookie key为 cookie 键设置随机指数值
【发布时间】:2016-03-17 18:11:30
【问题描述】:

是否可以使用这样的代码获得长度为 17 的字符串? 我们将 cookie 保存在客户端的浏览器中,然后从该浏览器中获取它。

function getPartnerVisitorId() {
    var pvid = cookies.get('pvid') || Math.floor(Math.random() * Math.pow(10, 15)).toString();
    cookies.setOnRoot('pvid', pvid, 365 * 24 * 60 * 60);
    return pvid;
};

我们认为“pvid”的最大长度应为 16 位,但有时(大约 5% 的 cookie)我们会得到此 cookie 的 17 位长度。

我们还注意到,所有奇怪的 cookie 都是偶数,其中大多数 (75%) 的最后一位数字为零

【问题讨论】:

    标签: javascript string random pow floor


    【解决方案1】:

    您正在处理的问题与 IEEE 754 浮点数的性质有关 - JavaScript 中用于保存 Number 的类型,Java 和 C 中用于保存 double 等的类型。这些数字存储在一种科学记数法,形式为

    [+/-] 1.[some value] * 2^[some other value].

    这会导致您获得大约 15 个有效十进制数字,这些数字特别擅长表达 2 的幂。

    通过将Math.random() 乘以Math.pow(10,15),您会遇到此方案的两个问题:

    • 您的数字用完了,因此要截断底部的最后几位(因此您的数字总是偶数)
    • 您正在尝试表示 10 的幂,但它并不总是能准确地做到这一点(因此有时您会得到 17 位数字的密钥)。

    要解决这些问题并获得所需的恒定长度随机密钥,请做两件事:

    • Math.random() 乘以Math.pow(2,x)(其中x 是您尝试找到合适长度的数字)- 2^任何东西都可以用浮点数精确表示。
    • toString(), 方法中,插入一个整数参数,该参数是 2 的幂(例如 8 或 16) - 这将导致数字转换为以 8 或 16 为基数的字符串系统。这将防止可变长度的键,也防止舍入。

    var pvid = cookies.get('pvid') || Math.floor(Math.random() * Math.pow(8, 15)).toString(8);

    【讨论】:

    • 有道理,谢谢。但我已经运行了这段代码'Math.floor(Math.random() * Math.pow(10, 15)).toString();'进行了数百万次迭代,却没有得到任何 17 甚至 16 位长度的数字。它如何取决于浏览器的版本或类似的东西?
    • 对于他的问题还有一个愚蠢的解决方案,我想这对它的问题来说已经足够好了:Math.random().toString().substr(2, 16)
    • @nemoinho - 由于这是一个根本不同的解决方案,您可以将其发布为答案而不是评论。
    猜你喜欢
    • 2021-08-25
    • 1970-01-01
    • 2019-11-02
    • 2017-02-28
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多