实现密码生成器的思路

在项目中有这样一个需求:需要生成一组随机密码,确保安全性。因此,我去翻了一个项目的代码。这里是具体的代码

function GeneratePassword() {

    if (parseInt(navigator.appVersion) <= 3) {
        alert("Sorry this only works in 4.0+ browsers");
        return true;
    }

    var length=8;
    var sPassword = "";
    length = document.aForm.charLen.options[document.aForm.charLen.selectedIndex].value;

    var noPunction = (document.aForm.punc.checked);
    var randomLength = (document.aForm.rLen.checked);

    if (randomLength) {
        length = Math.random();

        length = parseInt(length * 100);
        length = (length % 7) + 6
    }


    for (i=0; i < length; i++) {

        numI = getRandomNum();
        if (noPunction) { while (checkPunc(numI)) { numI = getRandomNum(); } }

        sPassword = sPassword + String.fromCharCode(numI);
    }

    document.aForm.passField.value = sPassword

    return true;
}

function getRandomNum() {

    // between 0 - 1
    var rndNum = Math.random()

    // rndNum from 0 - 1000
    rndNum = parseInt(rndNum * 1000);

    // rndNum from 33 - 127
    rndNum = (rndNum % 94) + 33;

    return rndNum;
}

function checkPunc(num) {

    if ((num >=33) && (num <=47)) { return true; }
    if ((num >=58) && (num <=64)) { return true; }
    if ((num >=91) && (num <=96)) { return true; }
    if ((num >=123) && (num <=126)) { return true; }

    return false;
}

上完代码,接下来来分析一下这段代码

首先,这段代码中有三个函数,其关系如下图所示

密码生成器各函数关系图

其中 getRandomNum 生成了一个范围在 33 – 127 的数字。这里是由于在后续生成随机字符串时,用的是 String.fromCharCode,当数字在 33~127 之间时,能够确保生成的数字在输入时比较简单。

String.fromCharCode 的测试结果

checkPunc 则是检测输出的文字是否可以直接发音,这涉及到记忆的难度的问题,在一个长的字符串中,记忆 ABCD 肯定比记忆逗号、破折号、句号等符号要简单一些,毕竟字母肯定要好记忆点,可以自编语句来实现。

接下来我们来看最核心的 GeneratorPassword 函数:如果将其中的 Dom 操作都忽略掉,并设置一个值。并进行配置后,代码如下:

function GeneratePassword() {

    // 检测浏览器支持
    if (parseInt(navigator.appVersion) <= 3) {
        alert("Sorry this only works in 4.0+ browsers");
        return true;
    }

    var length=8;
    var sPassword = "";
    length = 10 // 此处代码原为使用 dom 函数获取表单数据的代码,来实现自定义长度的功能。

    var noPunction = false// 此处代码原为获取表单数据的代码,控制是否检测密码的可读性
    var randomLength = false // 此处代码原为获取表单数据的代码,控制是否使用随机长度。

    // 如果使用随机长度的密码,则进入循环
    if (randomLength) {
        length = Math.random();

        length = parseInt(length * 100); // 生成 0 ~ 100 之间的数字
        length = (length % 7) + 6 // 对生成的长度取余,则最短为6,最长为12 
    }

    // 根据长度进行循环
    for (i=0; i < length; i++) {

        numI = getRandomNum();  // 获取一个随机数
        if (noPunction) { while (checkPunc(numI)) { numI = getRandomNum(); } } // 如果需要判断发音,进行发音判断,判断失败就重新生成,直到成功。

        sPassword = sPassword + String.fromCharCode(numI); // 将生成的字符串加入到原有的字符串最后
    }

    // 设置代码到 Dom 元素中

    return true;
}

其代码逻辑图如下

密码生成器的代码逻辑图

使用 JavaScript 来导出 CSV

造了个油猴脚本的轮子

由于要做一个 UserScript 用到了这个功能,便顺便记录下来。

数组结构

var data = [
{
"title" :value,
"href" : value
},
...
]

生成 CSV 字符串

function convertArrayOfObjectsToCSV(args) {  
        var result, ctr, keys, columnDelimiter, lineDelimiter, data;

        data = args.data || null;
        if (data == null || !data.length) {
            return null;
        }

        columnDelimiter = args.columnDelimiter || ',';
        lineDelimiter = args.lineDelimiter || '\n';

        keys = Object.keys(data[0]);

        result = '';
        result += keys.join(columnDelimiter);
        result += lineDelimiter;

        data.forEach(function(item) {
            ctr = 0;
            keys.forEach(function(key) {
                if (ctr > 0) result += columnDelimiter;

                result += item[key];
                ctr++;
            });
            result += lineDelimiter;
        });

        return result;
    }

生成 CSV 文件,并下载

function downloadCSV(args) {  
        var data, filename, link;
        var csv = convertArrayOfObjectsToCSV({
            data: data
        });
        if (csv == null) return;

        filename = args.filename || 'export.csv';

        if (!csv.match(/^data:text\/csv/i)) {
            csv = 'data:text/csv;charset=utf-8,' + csv;
        }
        data = encodeURI(csv);

        link = document.createElement('a');
        link.setAttribute('href', data);
        link.setAttribute('download', filename);
        link.click();
    }

 

 

代码来源:https://halistechnology.com/2015/05/28/use-javascript-to-export-your-data-as-csv/