## Perl serial key generator

The Problem is that I need a god solution to make a serial key in Perl, and so I wrote this program.You could give him a ID to generate a unique serial or you could just use the random function.

serial

is the function for the serial, it generates 10 Blocks of 8 numbers, the first is the ID, with the ID you could generate the serial, then from 2-9 is the serial and the last block is a quick checksum.

quick_keycheck

It calculates a simple checksum from block 2-9 and number 10. the checksum.Its just a simple calculation to implement it in your client software so they don’t could reverse engineer your serial generator code.

full_keycheck

This makes the full key check you should use this script only in your server software.

```print "\$_ -> ",serial(\$_)." - ".quick_keycheck(serial(\$_))." - ".full_keycheck(serial(\$_)).\$/ for(0..20);

sub serial {
my \$k1 = \$_[0]//int(rand(999999));
my \$k2 = 0;
my \$k3 = 0;
my \$k4 = 0;
my \$k5 = 0;
my \$k6 = 0;
my \$k7 = 0;
my \$k8 = 0;
my \$k9 = 0;
my \$quicksum = "";
my \$cache = \$k1;

#calculate
\$k2 = digit_sum(\$cache);
\$cache *= \$cache*\$k2;
\$k3 = digit_sum(\$cache);
\$k2 = substr( int(\$k1*2+\$k2*17), 0, 6 );
\$k3 = substr( int(\$k1*2+\$k2*13), 0, 6 );
\$k4 = substr( int(\$k1*2+\$k2*11+\$k3), 0, 6 );
\$k5 = substr( int(\$k1*3+\$k2*7+\$k3*\$k4), 0, 6 );
\$k6 = substr( int(\$k1*4+\$k2*5+\$k3*\$k4+\$k5), 0, 6 );
\$k7 = substr( int(\$k1*5+\$k2*3+\$k3*\$k4+\$k5*\$k6), 0, 6 );
\$k8 = substr( int(\$k1*6+\$k2*2+\$k3*\$k4+\$k5*\$k6+\$k7), 0, 6 );
\$k9 = substr( int(\$k1*6+\$k2*2+\$k3*\$k4+\$k5*\$k6+\$k7+\$k9), 0, 6 );

#shuffle
for(1..3){
\$cache = \$k2+\$k3+\$k4+\$k5+\$k6+\$k7+\$k8+\$k9+(\$k1)x!!!(\$cache%2);
\$k2 = substr( int(\$k3*\$k8+\$k4*\$k5+\$k6*\$k7+(\$k2%2)+\$cache), 1, 7 );
\$k3 = substr( int(\$k4*\$k7+\$k5*\$k6+\$k7*\$k8+(\$k3%3)+\$cache), 1, 7 );
\$k4 = substr( int(\$k5*\$k6+\$k6*\$k7+\$k8*\$k2+(\$k4%5)+\$cache), 1, 7 );
\$k5 = substr( int(\$k6*\$k5+\$k7*\$k8+\$k2*\$k3+(\$k5%7)+\$cache), 1, 7 );
\$k6 = substr( int(\$k7*\$k4+\$k8*\$k2+\$k3*\$k4+(\$k6%11)+\$cache), 1, 7 );
\$k7 = substr( int(\$k8*\$k3+\$k2*\$k3+\$k4*\$k5+(\$k7%13)+\$cache), 1, 7 );
\$k8 = substr( int(\$k2*\$k2+\$k3*\$k4+\$k5*\$k6+(\$k8%17)+\$cache), 1, 7 );
\$k9 = substr( int(\$k1+\$cache+digit_sum(\$k9)+digit_sum(\$cache)*digit_sum(\$1)), 0, 6 );
}

#create quicksum
\$quicksum = quickcheck(\$k2,\$k3,\$k4,\$k5,\$k6,\$k7,\$k8,\$k9);
#return
return(sprintf('%06s-%06s-%06s-%06s-%06s-%06s-%06s-%06s-%06s-%06s',\$k1,\$k2,\$k3,\$k4,\$k5,\$k6,\$k7,\$k8,\$k9,\$quicksum));
}

sub digit_sum {
my \$out = 0;
while(\$_[0] =~ /(.)/g) {\$out += \$1;}
return(\$out);
}

sub quick_keycheck {
my (\$k1,\$k2,\$k3,\$k4,\$k5,\$k6,\$k7,\$k8,\$k9,\$quicksum) = split("-",\$_[0]);
return(quickcheck(\$k2,\$k3,\$k4,\$k5,\$k6,\$k7,\$k8,\$k9) eq \$quicksum);
}

sub full_keycheck {
my (\$k1,\$k2,\$k3,\$k4,\$k5,\$k6,\$k7,\$k8,\$k9,\$quicksum) = split("-",\$_[0]);
if(\$k1==0){return(0)}
return(serial(\$k1) eq \$_[0]);
}

sub quickcheck {
my (\$k2,\$k3,\$k4,\$k5,\$k6,\$k7,\$k8,\$k9) = @_;
my \$out = 0;
\$out += digit_sum(\$_) for(@_);
for(1..3){
\$out += digit_sum(\$out)+substr(int(\$k2+\$k3+\$k4+\$k5+\$k6+\$k7+\$k8+\$k9), 0, 8 );
}
if(\$out==0){return(0)}
return(sprintf('%06s',substr(\$out, 1, 7)));
}```

Serials from 1 to 20 :

```0 -> 000000-000000-000000-000000-000000-000000-000000-000000-000000-000000 -  - 0
1 -> 000001-3998721-7745224-0599396-2052866-2216425-6579748-5182280-312901-6063028 - 1 - 1
2 -> 000002-9388879-1124434-5415065-3373564-8276835-2940278-2216239-295806-9093630 - 1 - 1
3 -> 000003-8136824-2769572-3221522-0237729-3271546-0220234-5907911-286637-2156204 - 1 - 1
4 -> 000004-3076279-6603463-8952898-0437658-4536704-5993699-0569181-331545-1504608 - 1 - 1
5 -> 000005-1975766-4030413-2291740-0469716-2407084-8577044-4270996-402439-3275906 - 1 - 1
6 -> 000006-6013437-5064470-1421661-0737926-5095564-5504051-7121567-341836-3901797 - 1 - 1
7 -> 000007-4968284-8541557-2572685-7292731-6322198-1697878-2764690-199017-0307747 - 1 - 1
8 -> 000008-0771673-4039673-2219286-1344400-6884137-0254807-8815735-326078-3967676 - 1 - 1
9 -> 000009-1784857-2796964-4190696-3833352-3627062-7471493-8810778-326826-8526432 - 1 - 1
10 -> 000010-8454487-5887503-7485665-4249980-7497945-3339953-4741639-564253-2666463 - 1 - 1
11 -> 000011-3822996-4816144-1076432-6210880-6838638-1214082-2273539-295931-9646262 - 1 - 1
12 -> 000012-3105051-5182692-1252777-0574682-3206422-2380572-7976814-420609-2299157 - 1 - 1
13 -> 000013-2497334-3623028-3811689-6380523-4720311-1482726-0164622-368791-9147360 - 1 - 1
14 -> 000014-0258939-4971510-9606881-8702706-4291176-3432311-5172619-222485-0997619 - 1 - 1
15 -> 000015-3144206-6477344-1667938-9924078-1751310-3248974-8070005-289566-0372059 - 1 - 1
16 -> 000016-7893562-1201635-3529485-2735528-9729948-2572572-3166053-346847-3527229 - 1 - 1
17 -> 000017-3685743-3103374-4084623-5118118-0459651-0630184-8613410-483937-8537423 - 1 - 1
18 -> 000018-2601883-2383892-7972378-8424561-1093898-9865097-4990720-264832-1279216 - 1 - 1
19 -> 000019-1294422-8138122-9758807-3694786-1036395-0535036-4923173-259514-8921080 - 1 - 1
20 -> 000020-3731936-0417432-5018774-1448438-3551307-5267837-1166230-395351-2992236 - 1 - 1```

This is a little test to make the client software in JavaScript:

```<!DOCTYPE html>
<html>

<body>
<script>
function myFunction() {
if(document.getElementById("key").value != ""){
var res = document.getElementById("key").value.split("-");
var out = 0;
for(var i = 1;i <= 8;++i){
out += 1*digit_sum(res[i]);
}
console.log(out);

for(var i = 1;i <= 3;++i){
out +=
1*digit_sum(out)+
1*(((1*res[1]+1*res[2]+1*res[3]+1*res[4]+1*res[5]+1*res[6]+1*res[7]+1*res[8])+"").substring(0,8));
console.log(out);
}

out = (out+"").substring(1,8)
out -= res[9];

if(out == res[9]){
document.getElementById("result").innerHTML = "Key okay!";
return(0);
}
document.getElementById("result").innerHTML =out ;// "Key okay!"
}else{
document.getElementById("result").innerHTML = "Key wrong!"
}
}
function digit_sum (number){
var out = 0;
for (var i = 0; i < number.length; i++) {
out += 1*number[i];
}
return(out);
}
</script>
<body>
<input type="text"id="key" rows="1" cols="50" onchange="myFunction()" onkeyup="myFunction()" placeholder="Your Regex here...">
<h5 id="result"></h5>

</body>

</html>```

but it only haves a different between 0 and 200 …. so its more try and error.

## Perl high precision calculation

If you want to make a high precision calculation with Perl you could use the bignum module.As little example:

```#!/usr/bin/perl
print 4/3,"\n";
use bignum;
print 4/3,"\n";```

And we could see the second result has a better accuracy than the default:

```1.33333333333333
1.333333333333333333333333333333333333333```

But you could improve this by setting the precision in Significant figures, like in this example we want 60.

```#!/usr/bin/perl
print sqrt(20),"\n";
use bignum ( p => -60 );;
print sqrt(20),"\n";```

As result we get:

```4.47213595499958
4.472135954999579392818347337462552470881236719223051448541794```

## Perl format number

This is a little script to format numbers in Perl:

```#!/usr/bin/perl

#test data
print myformat("1").\$/;
print myformat("213").\$/;
print myformat("333333").\$/;
print myformat("1231231.666").\$/;
print myformat("131233.54645").\$/;
print myformat("5553123123.44").\$/;
print myformat("55553123123.44").\$/;
print myformat("555553123123.44").\$/;
print myformat("5555553123123.44").\$/;
print myformat("55555553123123.44").\$/;
print myformat("555555553123123.44").\$/;

#format sub
sub myformat {
my (\$f,\$s) = split(/\./o,sprintf("%.2f",\$_[0]));
\$f =~ s/(\d{3})(?:\.|\$)/.\$1/go while(\$f =~ /^\d{4}/o);
return(\$f.(",\$s")x!!(0+\$s));
}```

This is our result:

```1
213
333.333
1.231.231,67
131.233,55
5.553.123.123,44
55.553.123.123,44
555.553.123.123,44
5.555.553.123.123,44
55.555.553.123.123,44
555.555.553.123.123,44```

This is more fun than real use, I want Gandalf from Lord of the Rings to protect my word press login.Its really simple, just upload the images to your web space and then open the “/wp-login.php” and change the this:

```<div id="login">
<?php```

to this:

```<div id="login">
<?php```

and now I want another error image, for this find this part:

`echo '<div id="login_error">' . apply_filters( 'login_errors', \$errors ) . "</div>\n";`

`echo '<script>document.getElementById("login_img").src="/img/bwl.jpg";</script>';`

```#login {
margin: auto;
width: 640px;
}```

and now its looksÂ pretty like this:

And the error screen:

I hope you like it!

For a live preview look at http://scheinast.eu/wp-login.php.

## Perl && vs. and – || vs. or Benchmark

I want to compare the && vs. the and operator, and the || vs. or operator in Perl:

```#!/usr/bin/perl
use strict;
use Benchmark qw(:all) ;

my \$x = 100;
my \$y = 0;

cmpthese(-1, {
'and'  => sub {if(\$y and \$x){print;}print;},
'&&'   => sub {if(\$y &&  \$x){print;}print;},
});
cmpthese(-1, {
'or'   => sub {if(\$y or  \$x){print;}print;},
'||'   => sub {if(\$y ||  \$x){print;}print;},
});

++\$y;

cmpthese(-1, {
'and'  => sub {if(\$y and \$x){print;}print;},
'&&'   => sub {if(\$y &&  \$x){print;}print;},
});
cmpthese(-1, {
'or'   => sub {if(\$y or  \$x){print;}print;},
'||'   => sub {if(\$y ||  \$x){print;}print;},
});
```

First result (1 && 0) vs. (1 and 0):

```         Rate  && and
&&  4497569/s  -- -3%
and 4626070/s  3%  --```

Second result (1 or 0) vs. (1 || 0):

```        Rate   or   ||
or 2683073/s   -- -15%
|| 3163806/s  18%   --```

Third result (1 && 1) vs. (1 and 1):

```         Rate  && and
&&  2525239/s  -- -1%
and 2548621/s  1%  --```

Fourth result (1 or 1) vs. (1 || 1):

```        Rate   or   ||
or 2912710/s   -- -33%
|| 4324590/s  48%   --```

It seems the “and” and “&&” don’t make really different, but the “or” and “||” operator seems different.I don’t know why the “||” are 18-48% faster than the “or” …. and the “and” is only about 1-3% faster.

Now we check if they work as they should:

```if(false() and true()){print;}print"END\n";
if(false() &&  true()){print;}print"END\n";
if(false() or  true()){print;}print"END\n";
if(false() ||  true()){print;}print"END\n";

if(true() and true()){print;}print"END\n";
if(true() &&  true()){print;}print"END\n";
if(true() or  true()){print;}print"END\n";
if(true() ||  true()){print;}print"END\n";

sub true() {print "sub true";return(1);}
sub false() {print "sub false";return(0);}```

result looks good they abort if a true is impossible:

```sub falseEND
sub falseEND
sub falsesub trueEND
sub falsesub trueEND
sub truesub trueEND
sub truesub trueEND
sub trueEND
sub trueEND```

That is more a check up and not really a Benchmark.