持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天, 点击查看活动详情

因为最近在申请微信支付的时候,需要设置APIv2密钥(32位随机密码:大小写字母、数字),之前使用过的相关工具网站也没有收藏的习惯,每次度娘出来一大堆,一时间不知道使用哪个好,有的网页生成的密码,在设置的时候还提示不正确,因此打算自己实现一个生成随机密码的小工具。

该密码生成器,可以自由选择由大写英文字母,小写英文字母,数字,特殊符号组成,再选择需要生成的密码位数,点击“随机生成密码”按钮生成该位数的随机密码;点击“复制”按钮实现把生成显示的密码,复制到剪贴板。

  • 将生成大写字母、小写字母、数字、特殊符号的方法封装成各自的函数,都可以返回一个随机值
  • a. 生成大写字母 (A-Z的Unicode 值从65-90)

    function getRandomUpper() {
        return String.fromCharCode(Math.floor(Math.random() * 26) + 65)
    

    b. 生成小写字母 (a-z的Unicode 值从97-122)

    function getRandomLower() {
        return String.fromCharCode(Math.floor(Math.random() * 26) + 97)
    

    c. 生成数字 (0-9的Unicode 值从48-57)

    function getRandomNumber() {
        return String.fromCharCode(Math.floor(Math.random() * 10) + 48)
    

    d. 生成特殊字符

    function getRandomSymbol() { const symbols = '!@#$%^&*(){}[]=<>/,.' return symbols[Math.floor(Math.random() * symbols.length)]

    c. 将上面这几个函数组成一个对象randomFunc

    const  randomFunc = {
        upper: getRandomUpper,
        lower: getRondomLower,
        number: getRandomNumber,
        symbol: getRandomSymbol
    

    引申的知识点:

  • fromCharCode() fromCharCode() 可接受一个指定的 Unicode 值,然后返回一个字符串。
    注意:该方法是 String 的静态方法,字符串中的每个字符都由单独的 Unicode 数字编码指定。
  • 使用语法:String.fromCharCode(num1, ..., numN)

    const a = String.fromCharCode(65);
    a 输出结果: A
    

    Math.floor() 返回一个表示小于或等于指定数字的最大整数(向下取整)。是 Math 的一个静态方法

    Math.random() 返回一个范围从0 到小于1的随机浮点数

    Math.random() * 26 表示[0,26)之间的随机数

  • 生成随机密码方法
  • 将是否选择大写英文字母,小写英文字母,数字,特殊符号这几个的状态值和密码位数作为生成随机密码方法的参数,筛选出作为密码组成部分,状态为选中的值(参数为true),将这些状态为选中的值,遍历循环取得属性的键名,根据键名调用randomFunc对象中的对应的方法,得到对应的返回值组成随机密码并返回;如果传入的参数值都为false,直接返回。

    function generatePassword(lower, upper, number, symbol, length) {
        console.log(lower, upper, number, symbol, length)
        let generatedPassword = ''
        const typesCount = lower + upper + number + symbol
       //Object.values(item)[0] 获取数组中每个对象的值  
       // 筛选出值为true(状态为选中的)的大写英文字母、小写英文字母、数字、特殊符号
        const typesArr = [{lower}, {upper}, {number}, {symbol}].filter(item => Object.values(item)[0] )
        // 状态都为未选中,则都为flase,加起来就是0;直接返回
        if(typesCount === 0) {
            return false
        for(let i = 0; i < length; i +=  typesCount) {
            // 遍历循环状态为选中的对象组成的数组,获取每个对象的属性名,根据属性名调用各自生成函数
            typesArr.forEach(type => {
                const funcName = Object.keys(type)[0]
                generatedPassword += randomFunc[funcName]()
        // 截取选择的密码位数长度的随机密码
        const finalPassword = generatedPassword.slice(0, length)
        return finalPassword
    
  • 生成随机密码按钮点击事件
  • generateEl.addEventListener('click', () => {
        const length = +lengthEl.value
        const hasLower = lowercaseEl.checked
        const hasUpper = uppercaseEl.checked
        const hasNumber = numbersEl.checked
        const hasSymbol = symbolsEl.checked
        //把获得的随机密码展示到页面    
        resultEl.innerText = generatePassword(hasLower, hasUpper, hasNumber, hasSymbol, length)
    
    clipboardEl.addEventListener('click',copyPageUrl)
    async function copyPageUrl() {
        const password = resultEl.innerText
        if(!password) { return }
        try {
            await navigator.clipboard.writeText(password);
            alert('密码复制成功!')
        } catch (err) {
            alert("密码复制失败!");
    

    注:关于剪切板复制内容的功能可以查看这篇文章《js实现简单功能合集(三)》

    分类:
    前端
    标签: