【问题标题】:Nodejs generate short unique alphanumericNodejs生成简短的唯一字母数字
【发布时间】:2018-08-23 18:44:22
【问题描述】:

我想生成一个简短的唯一字母数字值,用作在线购买的确认码。我正在调查https://github.com/broofa/node-uuid,但他们的 uuid 太长了,我希望它们的长度约为 8 个字符。实现这一目标的最佳方法是什么?

【问题讨论】:

  • unique 和 short 不能并驾齐驱,除非你能保证它们有一个单一的来源,或者有一些互锁的方法,这样两个服务器就不会生成相同的字符串。
  • 如果您使用哈希函数,您可以尝试确定哈希结果的当前最短子字符串,类似于 git 如何缩写提交哈希。

标签: javascript node.js


【解决方案1】:

10/23/15:请参阅下面的 hashids 答案!

您可以借鉴 URL 缩短模型并执行以下操作:

(100000000000).toString(36);
// produces 19xtf1ts

(200000000000).toString(36);
// produces 2jvmu3nk

只需增加数字以保持其唯一性:

function(uniqueIndex) {
    return uniqueIndex.toString(36);
}

注意,这仅对“单实例”服务真正有用,这些服务不介意按顺序排列(通过基本增量)具有一定程度的可预测性。如果您需要跨多个应用程序/数据库实例的真正独特的价值,您真的应该考虑为某些 cmets 提供更全功能的选项。

【讨论】:

  • 感谢您的提示。我最终使用了类似于您提供的内容: var now = new Date(); Math.floor(Math.random() * 10) + parseInt(now.getTime()).toString(36).toUpperCase()
  • parseInt 添加了什么? (100000000000).toString(36) 不也能正常工作吗?
  • @teggy,使用随机数有什么意义? (+new Date()).toString(36) 应该给你唯一的 id。
  • 或者:Array.apply(0, Array(n)).reduce(function(p){return p + (Math.random() * 1e18).toString(36)}, '') 将生成一个大约 (12 * n) 长度的字符串
  • 这种方法的唯一缺陷是它不能保证并行环境中的唯一性。两台机器或进程可能同时生成一个代码,您可能会发生冲突。
【解决方案2】:

这个有点晚了,但似乎 hashids 在这种情况下工作得很好。

https://github.com/ivanakimov/hashids.node.js

hashids(哈希 ID)从无符号整数创建简短、唯一、可解密的哈希

var Hashids = require('hashids'),
hashids = new Hashids('this is my salt');

var hash = hashids.encrypt(12345);
// hash is now 'ryBo'

var numbers = hashids.decrypt('ryBo');
// numbers is now [ 12345 ]

如果您想定位 ~ 8 个字符,您可以这样做,以下要求至少 8 个字符。

hashids = new Hashids("this is my salt", 8);

然后这个:

hash = hashids.encrypt(1);
// hash is now 'b9iLXiAa'

接受的答案是可预测/可猜测的,这个解决方案应该是唯一的和不可预测的。

【讨论】:

  • 从 1.0.0 开始更新 hashids。几个公共函数重命名更合适:Function encrypt() 改为 encode()Function decrypt() 改为 decode()Function encryptHex( )改为encodeHex()函数decryptHex()改为decodeHex()
  • 链接已损坏。
  • 加密和解密对于简单的 ID 生成来说可能是昂贵的操作
【解决方案3】:

安装 shortId 模块 (https://www.npmjs.com/package/shortid)。 默认情况下,shortid 会生成 7-14 个 url 友好字符:A-Z、a-z、0-9、_- 但您可以根据需要将 - 和 _ 替换为其他字符。 现在,当您将对象保存在数据库中时,您需要以某种方式将此 shortId 粘贴到您的对象上。最好的方法是像这样将它们粘贴在 Schema 中:

var shortId = require('shortid');
var PurchaseConfirmationSchema = mongoose.Schema({
  /* _id will be added automatically by mongoose */
  shortId: {type: String, unique: true, default: shortId.generate}, /* WE SHOULD ADD THIS */
  name: {type: String},
  address: {type: String}
});

我已经在这里回答了类似的问题:

Shorten ObjectId in node.js and mongoose

【讨论】:

  • 嗨,即使服务器重新启动,shortId 也会给出唯一的字符串吗?
  • 但是它需要一个正好有 64 个字符的字典,所以即使你替换 - 和 _ 也不会是字母数字。
【解决方案4】:

为此,我编写了一个模块,可以做到这一点,甚至更多。 看它的页面:id-shorter

【讨论】:

    【解决方案5】:

    如果每次在线购买都关联了唯一网址,则可以使用simple-short包的后端,不需要数据库连接,也不需要网络服务:

    var shorten=require('simple-short');
    
    shorten.conf({length:8}); // Default is 4. 
    
    code1=shorten('http://store.com/purchase1');
    code2=shorten('http://store.com/purchase2');
     //.. so on 
    

    【讨论】:

      【解决方案6】:

      基于此https://www.npmjs.com/package/randomstring

      var randomstring = require("randomstring");
      
      randomstring.generate();
      // >> "XwPp9xazJ0ku5CZnlmgAx2Dld8SHkAeT"
      
      randomstring.generate(7);
      // >> "xqm5wXX"
      
      randomstring.generate({
        length: 12,
        charset: 'alphabetic'
      });
      // >> "AqoTIzKurxJi"
      
      randomstring.generate({
        charset: 'abc'
      });
      // >> "accbaabbbbcccbccccaacacbbcbbcbbc"
      

      你可以这样做

      randomstring.generate({
        length: 8,
        charset: 'alphabetic'
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-09
        • 1970-01-01
        • 1970-01-01
        • 2011-08-18
        • 2013-12-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多