简体   繁体   中英

How can I generate a string of numbers and letters in Javascript?

I want to generate a line of numbers and letters in this format using Javascript.

Example: F35-HE4E-WAD-32S

So a line of 3-4-3-3 of random numbers and letters.

I would make a function which generates a random sequence matching a given template. Something like this:

function getSequence(template) {
    var r = '', ch, n;
    for (var i = 0; i < template.length; i++) {
        ch = template.substr(i, 1);
        if (ch == "d") {
            r += parseInt(Math.random() * 10);
        } else if (ch == "A") {
            r += String.fromCharCode(65 + parseInt(Math.random() * 26));
        } else if (ch == "w") {
            n = parseInt(Math.random() * 36);
            if (n > 9) {
                r += String.fromCharCode(55 + n);
            } else {
                r += n;
            }
        } else {
            r += ch;
        }
    }
    return r;
}
console.log(getSequence('Add-wwww-AAA-ddA'));

http://jsfiddle.net/xpt9od7c/

In the example given 'A' is used for capital letters, 'd' for digits (numbers) and 'w' for either. So 'Add-wwww' will return a sequence of one capital letter, two numbers, a hyphen, then four characters that can be either letters or numbers. You can then adapt according to what kind of sequence you need.

EDIT. Perhaps a cleaner and more reusable implementation is to make a function that converts a template character into a random character picked from the corresponding character set, then call Array.map to apply that function to each character of the template string.

var CHAR_SETS = {
    d: '0123456789',
    A: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
    w: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
};

function mapString(s, func) {
    return Array.prototype.map.call(s, func).join('')
}

function randChar(charType) {
    var chars = CHAR_SETS[charType];
    if (chars) {
        return chars.charAt(parseInt(Math.random() * chars.length));
    } else {
        return charType;
    }
}

console.log(mapString('Add-wwww-AAA-ddA', randChar));

http://jsfiddle.net/49hofey8/2/

Another option is to use replace :

var CHAR_SETS = {
    d: '0123456789',
    A: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
    w: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
};

function randChar(charType) {
    var chars = CHAR_SETS[charType];
    return chars.charAt(parseInt(Math.random() * chars.length));
}
console.log('Add-wwww-AAA-ddA'.replace(/[Adw]/g, randChar));

http://jsfiddle.net/so3pf271/1/

I would use something more generic.You can then reuse your functions for other code purposes.

 Number.MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; Number.MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER || -Number.MAX_SAFE_INTEGER; Number.toInteger = Number.toInteger || function(inputArg) { var number = +inputArg, val = 0; if (number === number) { if (!number || number === Infinity || number === -Infinity) { val = number; } else { val = (number > 0 || -1) * Math.floor(Math.abs(number)); } } return val; }; function clampSafeInt(number) { return Math.min(Math.max(Number.toInteger(number), Number.MIN_SAFE_INTEGER), Number.MAX_SAFE_INTEGER); } Array.isArray = Array.isArray || function(inputArg) { return {}.toString.call(inputArg) === '[object Array]'; } function isString(inputArg) { return {}.toString.call(inputArg) === '[object String]'; } function generateChars(first, last) { first = isString(first) && first.length ? first.charCodeAt(0) : 0; last = isString(last) && last.length ? last.charCodeAt(0) : 0; var chars = [], index; for (index = first; index <= last; index += 1) { chars.push(String.fromCharCode(index)); } return chars; } function randomInt(min, max) { var tmp, val; if (arguments.length === 1) { max = min; min = 0; } min = clampSafeInt(min); max = clampSafeInt(max); if (min > max) { tmp = min; min = max; max = tmp; } tmp = max - min + 1; if (tmp > Number.MAX_SAFE_INTEGER) { throw new RangeError('Difference of max and min is greater than Number.MAX_SAFE_INTEGER: ' + tmp); } else { val = Math.floor(Math.random() * tmp) + min; } return val; } function stringFromPool(ary, howMany) { var str = ''; if (Array.isArray(ary)) { for (index = 0, howMany = Number.toInteger(howMany); index < howMany; index += 1) { str += ary[randomInt(ary.length - 1)]; } } return str; } var getSequence = (function() { var lower = generateChars('a', 'z'), upper = generateChars('A', 'Z'), digit = generateChars('0', '9'), lowerDigit = lower.concat(digit), upperDigit = upper.concat(digit), all = lower.concat(upper, digit); return function(template) { var str = '', index, length, chr; if (isString(template) && template.length) { for (index = 0, length = template.length; index < length; index += 1) { chr = template.charAt(index); switch (chr) { case 'a': str += stringFromPool(lower, 1); break; case 'A': str += stringFromPool(upper, 1); break; case 'd': str += stringFromPool(digit, 1); break; case 'c': str += stringFromPool(lowerDigit, 1); break; case 'C': str += stringFromPool(upperDigit, 1); break; case 'x': str += stringFromPool(all, 1); break; default: str += chr; } } } return str; }; }()); function generatePattern() { return getSequence('CCC-CCCC-CCC-CCC'); } function runMaxTimes(fn, howMany) { howMany = Number.toInteger(howMany); var count = 0; return function() { if (count < howMany) { count += 1; return fn.apply(this, arguments); } }; } document.getElementById('generate').addEventListener('click', runMaxTimes(function(e) { this.textContent += generatePattern() + '\\n'; }, 5).bind(document.getElementById('out')), false); 
 <button id="generate">Generate</button> <pre id="out"></pre> 

A VERY simple way to do it would be to create an string of all of the characters that you want to include (digits and uppercase letters, in your case) and then use random number generation to pick which character to add from that string. You would then repeat this process with a loop . . . inserting dashes, where appropriate . . . until you had built out the string.

Something like this:

var sValidCharacters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var sCharCode = "";

for (i = 0; i < 13; i++) {
    sCharCode = sCharCode + sValidCharacters.charAt(parseInt(Math.random() * sValidCharacters.length));

    if ((i === 2) || (i === 6) || (i === 9)) {
        sCharCode = sCharCode + "-";
    }
}

console.log(sCharCode);

The nice thing about this approach is that, since it uses the length of sValidCharacters when determining the random number, you can add or subtract valid characters from that "source string", without changing any of the code.

Some sample outputs from a few test runs:

HF1-EH46-RKP-8OL
VJ6-TRE1-DVA-WR7
156-ODA4-350-TP5
XBA-Q599-KZJ-FST
N82-DNM8-QSS-GUK

EDIT:

I took a second pass to make it a little more flexible, so that all you need to do is change parameters to generate the code of your choice. Here is the new "functionized" version:

function generateCode(sSourceCharacters, iCodeLength, sSeperator, aSeparatorPositions) {
    var sNewCode = "";

    for (i = 0; i < iCodeLength; i++) {
        sNewCode = sNewCode + sSourceCharacters.charAt(parseInt(Math.random() * sSourceCharacters.length));

        if (aSeparatorPositions.indexOf(i + 1) !== -1) {
            sNewCode = sNewCode + sSeperator;
        }
    }

    return sNewCode;
}

This way, you can pass in any parameters that you want, to generate a code, based on what you need. For your specific question, the options would be passed like this:

var charGroup = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var length = 13;
var divider = "-";
var dividerLocations = [3, 7, 10]; // the numbers indicate which character to place the divider after

var generatedCode = generateCode(charGroup, length, divider, dividerLocations);

But, you could also pass in something like:

var charGroup = "0123456789";
var length = 11;
var divider = ".";
var dividerLocations = [3, 6, 9];

. . . to get randomly generated IP addresses (though, in no way guaranteed to be valid :D ): Examples:

235.232.608.74
125.227.649.68
983.678.369.71
605.708.890.97
537.554.201.23

Or this, to generate a random, 4-letter, "encoded" swear word: :D

var charGroup = "!@#$%^&*()?";
var length = 4;
var divider = "";
var dividerLocations = [];

Results:

@%$%
)?$&
*&(!
!^@)
*))#

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM