V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
mogutouer
V2EX  ›  JavaScript

用 JS 根据字符串生成一个固定的随机数

  •  
  •   mogutouer · 2023-09-14 16:34:34 +08:00 · 1685 次点击
    这是一个创建于 436 天前的主题,其中的信息可能已经有所发展或是发生改变。
    例如有 URL 字符串好几条
    http://sample.com/a.jpg
    http://sample.com/b.jpg
    ...
    http://sample.com/x.jpg

    我想让每一条字符串最终生成一个固定的随机数。

    有点拗口,我想做的是每一个图片分配到一个 CDN 的图片前缀地址,例如

    http://sample.com/a.jpg
    http://sample.com/b.jpg
    变成
    http://img1.sample.com/a.jpg
    http://img2.sample.com/b.jpg

    我本来想用随机数 random ,但发现同一个图片会随机到两个地址,导致浏览器缓存不能利用。

    所以想要固定比如 a.jpg 一定生成 1 ,b.jpg 一定生成 2 ,文件名随机,但每个 URL 对应的结果是唯一。

    我想用 MD5 加密一下然后取第一位来随机成 1-10 ,但每个请求都 MD5 一下有点太浪费了,不知各位有无好的想法。
    13 条回复    2023-09-15 17:58:26 +08:00
    XiLingHost
        1
    XiLingHost  
       2023-09-14 16:37:12 +08:00
    常见的 hash 都有硬件加速的,有啥浪费?
    6379616e
        2
    6379616e  
       2023-09-14 16:51:21 +08:00
    随便引入一个 md5 的算法库,然后直接将最终的哈希 parseint 转一下就好了
    NoobNoob030
        3
    NoobNoob030  
       2023-09-14 16:53:09 +08:00   ❤️ 1
    为什么不计算一下 md5 的实际性能消耗呢
    throme
        4
    throme  
       2023-09-14 16:56:49 +08:00
    取每个字符的 ascii 的值然后连起来啊
    比如 ab -> 097098
    jifengg
        5
    jifengg  
       2023-09-14 16:58:05 +08:00
    用你熟悉的代码,把字符串“a.jpg”生成一个 int32 的 hash 值 m ,如果你 cdn 有 n 个,就分配的就是 m%n 。
    负载均衡常用的算法。
    myqoo
        6
    myqoo  
       2023-09-14 17:25:34 +08:00
    ```
    function strHash(str) {
    var sum = 0;
    for (var i = 0, n = str.length; i < n; i++) {
    sum = (sum * 31 + str.charCodeAt(i)) >>> 0;
    }
    return sum;
    }
    ```
    jiangzm
        7
    jiangzm  
       2023-09-15 00:46:52 +08:00
    简简单单:

    const buildUrl = url => url.split('').reduce((r, c) => r + c.charCodeAt(), 0) % 10 + 1;
    ysc3839
        8
    ysc3839  
       2023-09-15 01:22:45 +08:00 via Android
    这种需求没必要 MD5 ,直接 fnv hash 就完事了,代码非常简单
    https://github.com/schwarzkopfb/fnv1a/blob/master/index.js
    ysc3839
        9
    ysc3839  
       2023-09-15 01:28:24 +08:00 via Android
    @XiLingHost 常见 hash 没有硬件加速,最多就是用 SIMD 指令优化一下,个人认为算不上硬件加速。而且用纯 js 实现的话,js 引擎的 JIT 大概不会生成 SIMD 代码。
    你说的硬件加速可能指的是 x86 的 AES-NI 指令,这种是通过指令集实现的,和 SIMD 类似,js 引擎也不能生成这种代码。
    ysc3839
        10
    ysc3839  
       2023-09-15 01:31:16 +08:00 via Android
    不过 MD5 的性能消耗也没有那么大。在讨论抗暴力破解的时候,MD5 被认为是弱 hash 算法,在各类 hash 算法中性能消耗是比较小的、暴力破解耗时是较短的。
    Vegetable
        11
    Vegetable  
       2023-09-15 09:11:24 +08:00
    学而不思则罔,思而不学则怠。你这样“优化”做出来的结果想打败 md5 很难,没必要浪费这个时间。
    yidadaa
        12
    yidadaa  
       2023-09-15 11:02:57 +08:00
    试试 130 Byte 的依赖库 nanoid: https://github.com/ai/nanoid
    libook
        13
    libook  
       2023-09-15 17:58:26 +08:00
    Hash 算法( MD5 就属于其中一种)是行业通用做法,压测一下看看吧,在你的业务规模下到底需要多少性能。
    另外你都用 JS 了,就没必要在这个环节考虑性能问题了吧,profiling 之后把优化精力用在真正的瓶颈上。

    https://www.measurethat.net/Benchmarks/Show/6372/0/sha1-js
    这里有个几种方式用 JS 算 SHA-1 的压测页面,可以参考一下。

    我所了解到的情况是,Intel 、AMD 、Apple 的常用 CPU 都有 Hash 算法加速,比如 SHA-1 、SHA-256 、SHA-512 。如果性能不够,可以看看是不是可以用 WebAssembly 来调用 CPU 的 Hash 算法加速。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2678 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:05 · PVG 11:05 · LAX 19:05 · JFK 22:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.