嘿, 我是Mofei!
Generating Verification Codes and Letter Sequences with toString

Do you want to generate verification codes like "1d3ade" and "9ded19" with a better algorithm?
Do you want to quickly generate letter sequences like "ABCDEFGHIJKL"?

By using some "tricks" of toString, you can achieve the above requirements with an extremely simple algorithmic complexity.

What is toString?

I don't want to spend too much time introducing toString, but if you really don't know what toString is, then you might need to brush up on your front-end knowledge.

There are actually two forms of toString.

1. obj.toString()

All objects have a toString method, and most custom objects will return [object type]. Of course, you can also customize the toString method to achieve various purposes. But this is not the purpose of today's topic; if you want to learn more, you can refer to this link Object.prototype.toString() for detailed content.

2. numObj.toString([radix])

The second form is the toString method for the Number object, primarily used to convert numbers to strings. For details, you can refer to Number.prototype.toString(), but many times, we overlook the radix parameter.

radix is mainly used to specify the base of the original data, which is an integer between 2-36. So why is the maximum 36? You might better understand this by looking at a keyboard: there are a total of 10 Arabic numeral characters 0-9, plus 26 English characters a-z, adding up to exactly 36. This is what we call base-36. Of course, in some cases, uppercase letters A-Z are also included, which is what we commonly refer to as base-62. In some instances, base-62 is used to describe timestamps, for example:

Date (UTC) Base 62 epoch
1970-06-21 00:32:16 10000
1975-01-01 00:00:00 AfyFM
1980-01-01 00:00:00 LLwUi
2015-01-01 00:00:00 1Y6TBI
2020-01-01 00:00:00 1imRQe

Okay, having rambled on, let's get to the point.

Generating Random Verification Codes with toString()

If there's a need to generate a 4-digit verification code, where each digit is one of 0-9a-z, how would you implement it?

A rather clumsy method would be to create a map table first.

var map = [0,1,2,3,4,5,6,7,8,9,a,b,c,d,...,x,y,z]

Then generate 4 random sequences and concatenate them into a verification code.

var count = 4;
var code = [];
while(count--) {
    var index = Math.random() * 35 | 0;
    code.push(map[index])
}
var code = code.join('');

In the above method, we used for(while) to produce 4 random numbers and concatenated these results using the array's join() (of course, string concatenation is also viable).

If we are very familiar with toString(), we can achieve this using just a random number and eliminate the for loop and string concatenation, and even entirely discard the above map.

First, we know that 0-9a-z actually constitutes 36 digits. Therefore, the question becomes very simple: we generate a number in the range of 4 digits in base-36 and convert it to a string, which solves our problem.

For example:

(1231312).toString(36)   \ qe34 (The number 1231312 corresponds to its base-36 character)
(642312).toString(36)    \ drm0 (The number 642312 corresponds to its base-36 character)

Now it's a simple math problem. To produce a 4-digit base-36 number, its range is 1000 to zzzz, corresponding to decimal values of Math.pow(36,3) to (Math.pow(36,4)-1).

So, the complete code is as follows:

var start = Math.pow(36,3);
var end = (Math.pow(36,4)-1);
var number = start + Math.random()*(end-start) | 0;
var code = number.toString(36);

Very simple! With just 2 numbers plus one random number, everything is done.

Now some may ask, what if I need to change the length of the verification code? Simple, let's encapsulate it.

function getCode(len) {
    len = len || 4;
    var start = Math.pow(36,len-1);
    var end = (Math.pow(36,len)-1);
    var number = start + Math.random()*(end-start) | 0;
    var code = number.toString(36);
    return code;
}

Okay, this looks pretty good, but when we generate a 7-digit number, you will find it becomes a negative number. Surely, you are smart enough to know the answer. Now let's handle this situation.

function getCode(len) {
    len = len || 4;
    if (len > 6) {
        // If more than 6 digits, we generate multiple groups, each group 6 digits.
        var time = len/6|0;
        var lastNum = len%6;
        var code = [];
        for(var i=0; i<time; i++){
            code.push(generate(6));
        }
        if (lastNum) {
            code.push(generate(lastNum));
        }
        return code.join('');
    }else{
        return generate(len);
    }
    function generate(len) {
            var start = Math.pow(36,len-1);
            var end = (Math.pow(36,len)-1);
            var number = start + Math.random()*(end-start) | 0;
            var code = number.toString(36);
            return code;
    }
}

Let's give it a try.

getCode(40) //pvbj7mmri1l1q8x28baqs3sfp4hiczmiyh1pb40v

Generating Letter Sequences with toString()

Actually, once you understand the above method, generating letter sequences is also straightforward; just start accumulating from 10.

THE END

More Articles You Might Be Interested In

Did this post inspire any ideas? Share your thoughts in the comments!

avatar

Mofei's Friend (Click to edit)

Write something, I won't judge.

HI. I AM MOFEI!

NICE TO MEET YOU!