跳到主要内容

随机密码生成器

· 阅读需 4 分钟
lzw.

这里不会记录您的随机密码,请您妥善保存。


<div>
<el-row>
<el-col :span="4">
<div class="grid-content">选择字符</div>
</el-col>
<el-col :span="20">
<div class="grid-content">
<el-checkbox-group v-model="checkList">
<el-checkbox label="1">A-Z</el-checkbox>
<el-checkbox label="2">a-z</el-checkbox>
<el-checkbox label="3">0-9</el-checkbox>
<el-checkbox label="4">!@#$%^&*</el-checkbox>
</el-checkbox-group>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="4">
<div class="grid-content">密码长度</div>
</el-col>
<el-col :span="20">
<div class="grid-content">
<el-slider v-model="sliderValue"></el-slider>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="4">
<div class="grid-content">强度评估</div>
</el-col>
<el-col :span="20">
<div class="grid-content">
<el-input v-model="pwdValue" placeholder="输入字符" @click="inputSelect" ref="pwdValue">
<template #append>
<el-rate
v-model="scoreValue"
disabled
show-score
text-color="#ff9900"
score-template="{value}">
</el-rate>
</template>
</el-input>
</div>
<el-alert v-if="scoreLabel"
:closable="closable"
:title="scoreLabel"
type="success">
</el-alert>
<el-alert v-else
:closable="closable"
title="可以选择字符,生成随机密码"
type="info">
</el-alert>
</el-col>
</el-row>
</div>

<script>
import zxcvbn from 'zxcvbn'

export default {
data() {
return {
checkList: [],
sliderValue: 16,
scoreValue: 0,
scoreLabel: '',
pwdValue: '',
closable: false
}
},
watch: {
checkList(newVal) {
this.makePassWord()
},
sliderValue(newVal) {
this.makePassWord()
},
pwdValue(newVal) {
this.passwordStrength()
}
},
methods: {
inputSelect() {
this.$refs.pwdValue.select()
},
makePassWord() {
const lowerCase = 'abcdefghijklmnopqrstuvwxyz'
const upCase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
const number = '1234567890'
const special = '!@#$%^&*'

let randStr = ''
if (this.checkList.includes('1')) randStr += lowerCase
if (this.checkList.includes('2')) randStr += upCase
if (this.checkList.includes('3')) randStr += number
if (this.checkList.includes('4')) randStr += special

let length = randStr.length
let pwdStr = ''
for (let i = 0; i < this.sliderValue && randStr; i++) {
pwdStr += randStr[Math.floor(Math.random() * length)]
}

this.pwdValue = pwdStr
},

passwordStrength() {
const scoreLabel = ['太容易猜到了吧', '很容易就猜到了', '可以不容易猜了', '安全比较难猜到', '很安全很难猜到']
const pwdStr = this.pwdValue
const {score, guesses} = this.checkPassWord(pwdStr)

this.scoreValue = pwdStr ? score + 1 : 0
this.scoreLabel = pwdStr ? `这个密码${scoreLabel[score]},评估:一般破解${this.formatTime(guesses)},超级爆破的话可能${this.formatTime(guesses / 10e9)}` : ''
},

checkPassWord(value) {
try {
// console.log(zxcvbn(value))
return value ? zxcvbn(value) : 0
} catch (err) {
console.error(err)
}

// 0:太容易猜到了吧
// 1:很容易就猜到了
// 2:还是有点容易猜
// 3:安全比较难猜到
// 4:非常安全难猜到
let score = 0 //最初级别
if (/\d/.test(value)) {//如果用户输入的密码 包含了数字
score = 1
}
if (/[a-z]/.test(value)) {//如果用户输入的密码 包含了小写的a到z
score = 2
}
if (/[A-Z]/.test(value)) {//如果用户输入的密码 包含了大写的A到Z
score = 3
}
if (/\W/.test(value)) {//如果是非数字 字母 下划线
score = 4
}
return {score, guesses: 1}
},

formatTime(str) {
const seconds = Math.abs(str)
const arrN = ['上万', '上千', '几百', '几十', '几', '一']
const arrR = ['估计要%年', '也要%个月', '需要%星期', '只要%天', '只要%小时', '就%分钟', '就%秒', '不到1秒'];
const arrT = [31536000, 2592000, 604800, 86400, 3600, 60, 1];

let time = '', index = arrT.length
for (let i = 0; i < arrT.length; i++) {
time = seconds / arrT[i]
if (time >= 1) {
time = Math.round(time)
index = i
break
}
}

// 如果是年
if (index === 0) {
switch (true) {
case time > 10000:
time = arrN[0];
break
case time > 1000:
time = arrN[1];
break
case time > 100:
time = arrN[2];
break
case time > 10:
time = arrN[3];
break
case time > 1:
time = arrN[4];
break
default:
time = arrN[5];
break
}
}

return arrR[index].replace('%', time)
}
}
}
</script>

<style lang="scss" scoped>
.el-row {
border: 1px solid #ccc;
padding: 10px;

&:last-child {
margin-bottom: 0;
}
}

.el-col {
border-radius: 4px;
}
</style>