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

WordPress change login image

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"> 
<h1><a href="<?php echo esc_url( $login_header_url ); ?>" title="<?php echo esc_attr( $login_header_title ); ?>" tabindex="-1"><?php bloginfo( 'name' ); ?></a></h1>
<?php

to this:

<div id="login"> 
		<img id="login_img" src="/img/ysnp.jpg" width="100%" height="100%"> 
<?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";

then add my line:

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

 

for a bigger view I changed the “/wp-admin/css/login.min.css”:

#login {
    margin: auto;
    padding: 8% 0 0;
    width: 640px;
}

 

and now its looks pretty like this:

gandalf1And the error screen:

gandalf2

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.