微信小程序使用openid生成唯一数字ID(哈希算法)
该方法生成的结果具有唯一性,不过生成结果的位数不能太少,至少要保证6位以上(多多益善),若需要更少位数的ID,建议像我一样加一个在数据库对比是否存在同一ID的步骤,若存在则调用方法重新生成,并增加生成结果的位数,直到确定唯一性。使用云数据库查询当前是否有这个 id,如果有,则重新调用该函数并增加转化结果的位数,直到得到一个不存在的 id。如果结果中有重复的数字,增加一个偏移量,直到结果中没有重复的
·
- 引入
crypto-js
库和云函数所需的模块。 -
const CryptoJS = require('./crypto-js'); // 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境 const db = cloud.database();
- 定义了一个
convertToUniqueDigits
函数,接收两个参数:需要转换的字符串和返回的结果的数字位数。
在函数内部,使用 sha256
函数将字符串转换为哈希值,然后将哈希值转换为数字,并将结果映射到指定的位数。
如果结果中有重复的数字,增加一个偏移量,直到结果中没有重复的数字。
使用云数据库查询当前是否有这个 id,如果有,则重新调用该函数并增加转化结果的位数,直到得到一个不存在的 id。这里可以省略,只要保证传进来的字符串具有唯一性,则转化的结果也具有唯一性。
如果不存在这个 id,直接返回结果。
-
/** * 将字符串转化为数字(若字符串唯一,则结果也具有唯一性) * * @param {String} s 需要转换的字符串 * @param {Number} n 返回的结果的数字位数 */ async function convertToUniqueDigits(s, n) { // 使用哈希算法将字符串转换为数字 const m = sha256(s); // 将哈希值转换为数字,并将结果映射到指定的位数 let x = parseInt(m, 16) % (10**n); // 如果结果中有重复的数字,增加一个偏移量 while (hasDuplicateDigits(x)) { x = (x + 1) % (10**n); } //检查数据库是否存在这个id const hasUID = await checkHasUid(x); //存在这个id,则重新调用该函数并增加转化结果的位数 if(hasUID>0){ return convertToUniqueDigits(s,n+1); //发现不能使用++,会无限循环 } //不存在这个ID,直接返回结果 else{ return x; } }
- 检查是否存在相同的uid
-
async function checkHasUid(uid){ const res = await db.collection('user_list').where({ uid: String(uid) }).count(); return res.total }
- 引用哈希算法
-
function sha256(s) { // 使用 SHA-256 哈希算法将字符串转换为哈希值 const hash = CryptoJS.SHA256(s); return hash.toString(CryptoJS.enc.Hex); }
- 检查数字中是否有重复的数字
-
function hasDuplicateDigits(x) { // 检查数字中是否有重复的数字 const digits = String(x).split(''); return digits.length !== new Set(digits).size; }
- 最后,将
convertToUniqueDigits
函数导出供其他模块使用。 -
module.exports = { convertToUniqueDigits: convertToUniqueDigits };
- 完整的代码
-
const CryptoJS = require('./crypto-js'); // 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境 const db = cloud.database(); /** * 将字符串转化为数字(若字符串唯一,则结果也具有唯一性) * * @param {String} s 需要转换的字符串 * @param {Number} n 返回的结果的数字位数 */ async function convertToUniqueDigits(s, n) { // 使用哈希算法将字符串转换为数字 const m = sha256(s); // 将哈希值转换为数字,并将结果映射到指定的位数 let x = parseInt(m, 16) % (10**n); // 如果结果中有重复的数字,增加一个偏移量 while (hasDuplicateDigits(x)) { x = (x + 1) % (10**n); } //检查数据库是否存在这个id const hasUID = await checkHasUid(x); //存在这个id,则重新调用该函数并增加转化结果的位数 if(hasUID>0){ return convertToUniqueDigits(s,n+1); //发现不能使用++,会无限循环 } //不存在这个ID,直接返回结果 else{ return x; } } //检查是否存在相同的uid async function checkHasUid(uid){ const res = await db.collection('user_list').where({ uid: String(uid) }).count(); return res.total } function sha256(s) { // 使用 SHA-256 哈希算法将字符串转换为哈希值 const hash = CryptoJS.SHA256(s); return hash.toString(CryptoJS.enc.Hex); } function hasDuplicateDigits(x) { // 检查数字中是否有重复的数字 const digits = String(x).split(''); return digits.length !== new Set(digits).size; } module.exports = { convertToUniqueDigits: convertToUniqueDigits };
调用示例:
-
const uniID = require('./uniqueID/unique-digits'); const s = event.openid; //用户openid const n = 7; //生成的ID位数 const uid = await uniID.convertToUniqueDigits(s, n); console.log(await uniID.convertToUniqueDigits('o8k0G44JT0OBw48J6yu4O6ueF978', 7)); //输出结果:9623014
哈希算法代码:
-
将下面的哈希代码复制到同一云函数下的js文件中,导入即可
-
哈希算法链接https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js
更多推荐
已为社区贡献1条内容
所有评论(0)