表单生成器(Form Builder)之伪造表单数据番外篇——随机车辆牌照

Posted du-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了表单生成器(Form Builder)之伪造表单数据番外篇——随机车辆牌照相关的知识,希望对你有一定的参考价值。

  前几天记录了一下表单生成器(Form Builder)之表单数据存储结构mongodb篇,之后便想着伪造一些数据。为什么要伪造数据呢?说来惭愧,因为拖拉拽设计表单以及表单对应的列表的PC端和移动端该显示哪些字段并且是否支持搜索打印(即表单的列表配置)等一系列配置都还没有做,还有就是前面只说了表单相关的设计,设计完了之后就是要使用(录入数据等)对应的这些也还没有做……总之就是现在只有数据结构,但是又想写一下查询,所以只能伪造一些数据。又想着这些数据尽量真实,所以就想写点代码来伪造数据。在写代码的时候,想随机生成一个车辆牌照,所以就有了这篇笔记。

  我去,说的太多了,赶紧进入主题。

  其实结合上篇笔记:获取一个随机数,之后生成一个车辆牌照还是挺简单的:首先随机获取一个省份,然后在数字和字母中随机获取6个字符,这样就拿到了一个车牌照。但是后来想了一下,既然是随机生成的,就会出现重复的,还有就是新生成的车牌照应该排除目前已经存在车牌照。下面看一下第一版,直接上一下代码:

var getRangeRandomNumber = function(num1,num2){ 
    num1 = Number.isInteger(num1) ? num1: 0;
    num2 = Number.isInteger(num2) ? num2: 0;
    var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
    return Math.round(Math.random() * (maxNum - minNum)) + minNum;
}; 
var getRandomLicensePlate1=function(){
    var strProvinceShorter="京";
    var strNumberLetter="12345";
    var tempRetLicensePlate=strProvinceShorter[getRangeRandomNumber(strProvinceShorter.length-1)];
    for(var i=0;i<5;i++){
        tempRetLicensePlate+=strNumberLetter[getRangeRandomNumber(strNumberLetter.length-1)];
    }
    return tempRetLicensePlate;
};
var tempLicensePlateObj={},licensePlateCounter=Math.pow(5,5);
for(var i=1;i<=licensePlateCounter;i++){
    var temp = getRandomLicensePlate1();
    if(tempLicensePlateObj[temp]){
        tempLicensePlateObj[temp]++;
    }
    else{
        tempLicensePlateObj[temp]=1;
    }
}
console.log("想要获取"+licensePlateCounter+"个不同的车牌照");
console.log("结果生成了"+Object.getOwnPropertyNames(tempLicensePlateObj).length+"个不同的车牌照");
console.log("*******************************下面是生成的车牌照详细*******************************");
console.log(JSON.stringify(tempLicensePlateObj));
console.log("*******************************同一个车牌照出现多次的详细:开始*******************************");
for (var key in tempLicensePlateObj) {
    if (tempLicensePlateObj.hasOwnProperty(key)) {
        if(tempLicensePlateObj[key]>1){
            console.log("车牌号:【"+key+"】生成了"+tempLicensePlateObj[key]+"次");
        }
    }
}
console.log("*******************************同一个车牌照出现多次的详细:结束*******************************");

  为了生成重复车牌照的概率大,第一次测试这里缩小了取值范围:

技术图片

技术图片

  看一下测试结果,重复率还是很高的,那么怎么生成一个不重复的车牌照呢?我想了一个笨方法:就是将已经存在车辆牌照作为参数传递给获取车辆牌照的方法,返回之前做一下判断,如果数组中包含了就递归获取,直到获取到一个不重复的,下面看一下测试二的代码:

var getRangeRandomNumber = function(num1,num2){ 
    num1 = Number.isInteger(num1) ? num1: 0;
    num2 = Number.isInteger(num2) ? num2: 0;
    var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
    return Math.round(Math.random() * (maxNum - minNum)) + minNum;
}; 
// 获取随机车牌
var getRandomLicensePlate2=(function f(excludeArr){
    if(!Array.isArray(excludeArr))excludeArr=[];
    //获取车牌照的逻辑
    var strProvinceShorter="京";
    var strNumberLetter="12345";
    var tempRetLicensePlate=strProvinceShorter[getRangeRandomNumber(strProvinceShorter.length-1)];
    for(var i=0;i<5;i++){
        tempRetLicensePlate+=strNumberLetter[getRangeRandomNumber(strNumberLetter.length-1)];
    }
    if(excludeArr.indexOf(tempRetLicensePlate)>=0){
        tempRetLicensePlate = f(excludeArr);
    } else {
        excludeArr.push(tempRetLicensePlate);
    }
    return tempRetLicensePlate;
});

var tempLicensePlateObj={},licensePlateCounter=Math.pow(5,5),tempAllLicensePlates=[];
for(var i=1;i<=licensePlateCounter;i++){
    var temp = getRandomLicensePlate2(tempAllLicensePlates);
    if(tempLicensePlateObj[temp]){
        tempLicensePlateObj[temp]++;
    }
    else{
        tempLicensePlateObj[temp]=1;
    }
}
console.log("想要获取"+licensePlateCounter+"个不同的车牌照");
console.log("结果生成了"+Object.getOwnPropertyNames(tempLicensePlateObj).length+"个不同的车牌照");
console.log("*******************************下面是生成的车牌照详细*******************************");
console.log(JSON.stringify(tempLicensePlateObj));
console.log("*******************************同一个车牌照出现多次的详细:开始*******************************");
for (var key in tempLicensePlateObj) {
    if (tempLicensePlateObj.hasOwnProperty(key)) {
        if(tempLicensePlateObj[key]>1){
            console.log("车牌号:【"+key+"】生成了"+tempLicensePlateObj[key]+"次");
        }
    }
}
console.log("*******************************同一个车牌照出现多次的详细:结束*******************************");

技术图片

  结果想到啊,栈溢出了……我都怀疑我的递归有问题,再看下一个测试结果

技术图片

  这次获取数量(最大值减5)比栈溢出的那次少了5次,就不报错了,接下来我又缩小取值范围,改成了四位数,看一下结果

技术图片

  这次测试也没有问题,最后两次没有问题是不是说明我写的递归没有问题……是不是真的因为内存装不下了???有哪位大神知道这是为什么或者有更好的获取车辆牌照的方法,还请指点一下,谢谢

  下面粘一下最终的代码:

var getRangeRandomNumber = function(num1,num2){ 
    num1 = Number.isInteger(num1) ? num1: 0;
    num2 = Number.isInteger(num2) ? num2: 0;
    var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
    return Math.round(Math.random() * (maxNum - minNum)) + minNum;
}; 
var getRandomLicensePlate=(function f(excludeArr){
    if(!Array.isArray(excludeArr))excludeArr=[];
    //    生成一个随机车联牌照
    var strProvinceShorter="京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川黔滇藏陕甘青宁新港澳台";
    var strNumberLetter="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var tempRetLicensePlate=strProvinceShorter[getRangeRandomNumber(strProvinceShorter.length-1)];
    for(var i=0;i<6;i++){
        tempRetLicensePlate+=strNumberLetter[getRangeRandomNumber(strNumberLetter.length-1)];
    }
    //    判断这个车联牌照是否存在
    if(excludeArr.indexOf(tempRetLicensePlate)>=0){
        tempRetLicensePlate = f(excludeArr);
    } else {
        excludeArr.push(tempRetLicensePlate);
    }
    return tempRetLicensePlate;
});

  最后又用这个测试了一下,生成100000个没问题:

技术图片

  又测了一下,生成1000000个,直接直接卡死了……算了,就到这里吧!

以上是关于表单生成器(Form Builder)之伪造表单数据番外篇——随机车辆牌照的主要内容,如果未能解决你的问题,请参考以下文章

第十篇:跨站请求伪造csrf

Django框架 之 Form表单和Ajax上传文件

Django框架 之 Form表单和Ajax上传文件

form builder angular 2 - 如何构造控件数组?

CSRF(跨站请求伪造)在 Laravel 中无法正常工作

使用PHP快速创建现代化的form表单,支持前端js扩展,就是方便