Storing a number inside a string using PHP


As we all know, we can store a set of boolean values (Yes or No, True of False) in a integer (signed or unsigned). For example, you can define constants which are power of two,

define('ATTRIB_1', 1);
define('ATTRIB_2', 2);
define('ATTRIB_3', 4);
define('ATTRIB_4', 8);
/* ..... */

A 32-bit integer can have 32 boolean values and 64-bit integer can have 64 boolean values. To check a state (integer) has somewhat attributes, you can do a logic and (&) operation, e.g.

function check($x) {
    return $x & ATTRIB_1;
}

A state can be combined, so you can do $x = $x | ATTRIB_1 or $x = ATTRIB_1 + ATTRIB_2 but using or (|) is preferred, because you will plus will not work as expected when the value contains that particular set bit unless you know it does not, e.g. constants definitions.

We can then first convert the integer to capital letters, using ‘A’ to ‘Z’ only.

function convertTo26($x) {
    $r = "";
    while ($x) {
      $r = chr(($x - 1) % 26 + 65).$r;
      $x = (int)(($x - 1)/ 26);
    }  
    return $r;

If you can limit the number of set bits, for example, if there are only 16 maximum flags, so you can limit this to 16-bit integer only, using & 0xFFFF.

We can also add a check, to verify easily the number in the string. We can count the number of set bits (For more information, please visit this C++ function).

 function getCounter($i) {
    $i = $i - (($i >> 1) & 0x55555555);
    $i = ($i & 0x33333333) + (($i >> 2) & 0x33333333);
    $i = ($i + ($i >> 4)) & 0x0f0f0f0f;
    $i = $i + ($i >> 8);
    $i = $i + ($i >> 16);
    return $i & 0x3f;
  }

If we limit the part of number representation to 5 digits, we can pad the ‘X’ because the 16-bit integer, the first number can only go up to ‘C’.

function getModuleString($x) {
    $x = $x & 0xFFFF;
    $y = convertTo26(getCounter($x)).convertTo26($x);
    return str_pad($y, 5, "X", STR_PAD_LEFT);
  }

Now, to decode the string to number, we can use a function to convert ‘A’…’Z’ string to number.

 function convertTo10($x) {
    $len = strlen($x);
    $r = 0;
    for ($i = 0; $i < $len; $i ++) {
      $r = $r * 26 + ord(strtoupper($x[$i])) - 64; 
    }
    return $r;
  }

But we have to skip the ‘X’ in the front, because it is used only for padding purposes. And then we extract the checksum. The rest of the string denote a integer, check the number of set bits to see it is equal to the checksum.

function getLic($x) {
    $len = strlen($x);
    $i = 0;
    while (($i < $len) && (($x[$i] == 'X') || ($x[$i] == 'x'))) $i++;
    if ($i == $len) return false;
    $c = $x[$i];
    $s = substr($x, $i + 1);
    $cc = convertTo10($c);
    $ss = convertTo10($s);
    if (getCounter($ss) == $cc) {
      return $ss;
    }
    return -1;// Invalid license key
  }

We can print the values to verify the correctness.

  for ($i = 0; $i < 100; $i ++) {
    $x = getModuleString($i);
    echo $i." = ".$x." = ".getLic($x)."
";
  }

And

  for ($i = 0; $i < 100; $i ++) {
    $x = getModuleString($i);
    echo $i." = ".$x."
";
  }

This will print out:

0 = XXXXX
1 = XXXAA
2 = XXXAB
3 = XXXBC
4 = XXXAD
5 = XXXBE
6 = XXXBF
7 = XXXCG
8 = XXXAH
9 = XXXBI
10 = XXXBJ
11 = XXXCK
12 = XXXBL
13 = XXXCM
14 = XXXCN
15 = XXXDO
16 = XXXAP
17 = XXXBQ
18 = XXXBR
19 = XXXCS
20 = XXXBT
21 = XXXCU
22 = XXXCV
23 = XXXDW
24 = XXXBX
25 = XXXCY
26 = XXXCZ
27 = XXDAA
28 = XXCAB
29 = XXDAC
30 = XXDAD
31 = XXEAE
32 = XXAAF
33 = XXBAG
/* ... */

So we can append this string into a key (e.g. License key) and decode the key string in the client side of the software. Based on the number (set of booleans), we can control the functionalities of the software.

This is OK if the license verification is done at server side because it doesn’t matter that the string is decrypted. The key is readonly so the users can’t do much regarding to the key string.

This serves the way to store a integer (hide it) in a license key string.

–EOF (The Ultimate Computing & Technology Blog) —

740 words
Last Post: C/C++ Coding Exercise - Unique Paths II - Dynamic Programming with Obstacles - Leetcode Online Judge - DP with Constraints
Next Post: Output a String to Console (BBG-DOS) using 6502 Assembly for 8-bit Famicom Clone BBG - Tutorial 4

The Permanent URL is: Storing a number inside a string using PHP (AMP Version)

Leave a Reply