increment alpha numerically values - php

Like the title suggests I need to do something like so...
$i++;//we all know this.
$value = 'a';
increment($value);// i need this functionality
//output
string [ b ]
///here are some more samples, to help you understand...
increment('b'); //output// c
increment('z'); //output// A [capital A not fussy but would be good :) ]
increment('9'); //output// a1
increment('a1'); //output// a2
increment('aa1'); //output// aa2
and so on...
UPDATE
well lets say I use numeric values
$id++;
I would end up with a massive number eventuall 1310743942525;
which can take alot more space than say `ab34c9" im trying to save length of characters to save on db ...

You try to treat it as a base 62 number:
http://www.pgregg.com/projects/php/base_conversion/base_conversion.php
with source code at
http://www.pgregg.com/projects/php/base_conversion/base_conversion.inc.phps
convert it to decimal, increment, and convert it back to base 62
UPDATE
From how I read the code, you could have a workflow like this:
$value = 'ab8Zb';
$value_base10 = base_base2dec($value, 62);
$value_base10++;
$value = base_dec2base($value_base10, 62); // should be 'ab8Zc'

If all you are trying to do is save database space, consider this.
In MySQL you can have a field with a type UNSIGNED BIGINT. The maximum size of this field is 18446744073709551615 and the storage space is only 8 bytes.
If you were to convert this number (1.844 x 10^19) to base-62, it would be represented as LygHa16AHYF. You would need a CHAR(11) (11 bytes) or a VARCHAR(11) (12 bytes) in order to store the converted number.
If you used VARCHAR for the field type, smaller numbers would take less space, but for the larger numbers it actually takes more. 8 bytes for a huge number is pretty minimal anyway. I would save the effort and just make the DB field a UNSIGNED BIGINT.

You can use ascii codes of each letter. This is just a simple example that will show you the idea, ofcourse it need a lot of modyfications if you want to increment 'aa1' into 'aa2' but impossible is nothig ;P You will just need to write few conditions.
function increment($value)
{
if(strlen($value)>1)
return false;
$asciiCode = ord($value);
return chr($asciiCode + 1);
}
http://www.asciitable.com/ - ASCII codes table :)

Related

Pack Convert byte array into UINT64

I want to convert byte array to UINT64 using PHP.
I can do this easily in C# but I want to do this in PHP.
Here is C# code.
bytes = Encoding.UTF8.GetBytes(hashed);
BitConverter.ToUInt64(bytes, 0);
I want to convert this to PHP.
I tried to use pack() function but this does not works.
Let's say this is a byte array.
$bytes = [101,102,54,55,99,55,56,49];
pack("J*","101","102","54","55","99","55","56","49");
This shows a warning.
epack(): 7 arguments unused on line
How can I fix this?
The major issue here (if I understand it correctly) is you're using PHP numbers to represent a byte array however unpack requires an input string. If you keep the array as is then PHP seems to just convert the numbers to strings meaning a 101 will be '101' which in turn is 3 bytes, which breaks the whole thing down.
You need to first convert the numbers to bytes. A byte is essentially as an unsigned char so you could first pack your array into unsigned chars and then unpack them:
$bytes = [101,102,54,55,99,55,56,49];
$unpacked = unpack("J", pack('C*', ...$bytes));
echo current($unpacked);
Explanation:
C is the pack code for unsigned char and * indicates that you need to use all array entries. This will generate a string of characters based on the array. You can then unpack this string using J (if you know for a fact that the bytes were generated in a big endian byte order) or P if you know the bytes were generated in little endian order or Q if you want to use the machine order. If the bytes were generated in the same machine then Q would probably be a better choice than J otherwise you need to know the endianess.
Example: http://sandbox.onlinephpfunctions.com/code/5cba2c29522f7b9f9a0748b99fac768012e759ce
Note: This is my personal understanding of what is happening so anyone with better pack/unpack knowledge can let me know if I got things wrong.

How to calculate check digit for Barcode 128 Auto php

I have a string which uses 128B and 128C conversion. ANCV0005YRF01234.
So
ANCV = 128B
0005 = 128C
YRF0= 128B
1234= 128 C
Cant use code 128 Auto as it converts the 0 after F into 128C (which i dont want.). At the moment using two different scripts and concatenating the barcode images,Need to calculate the check digit for that. Not sure how the check digit will be generated ?.
Any help is appreciated. Thanks
I got sum of characters by weights (rightmost column) from your example string = 5468 % 103 = 9 for a checksum if you want to switch back and forth.

PHP pack: do not really understand

I posted this (php pack: problems with data types and verification of my results) and found that I had two problems.
So here again only one issue (I solved the other one) Hopefully this is easy to understand:
I want to use the PHP pack() function.
1) My aim is to convert any integer number info a hex one of length 2-Bytes.
Example: 0d37 --> 0x0025
2) Second aim is to toggle high / low byte of each value: 0x0025 --> 0x2500
3) There are many input values which will form 12-Bytes of binary data.
Can anyone help me?
You just have to lookup the format table in the pack() manual page and it is quite easy.
2 bytes means 16 bits, or also called a "short". I assume you want that unsigned ... so we get n for big endian (high) and v for little endian (low) byte order.
The only potentially tricky part is figuring out how to combine the format and parameters, as each format character is tied to a value argument:
bin2hex(pack('nv', 34, 34)) // returns 00222200
If you need a variable number of values, you'll need agument unpacking (a PHP language feature, not to be confused with unpack()):
$format = 'nv';
$values = [34, 34];
pack($format, ... $values); // does the same thing
And alternatively, if all of your values should be packed with the same format, you could do this:
pack('v*', $values); // will "pack" as many short integers as you want

Choosing colours based on IP address

In my PHP (v5.2.17) script, I want to select a unique colour for the current user's entries, based on their IP address. I don't want to map the colour values from the hex codes, because I also want to fade the colours of each entry over time. The colour must always have one of the RGB values set to zero (it's like a set of bright, primary colours).
Is there a clever mathematical solution to do this?
I'd greatly appreciate if any math genuises reading this would share some insights. :-)
Are you really limiting yourself to just six "base" colors?
255 255 0
255 0 255
0 255 255
0 0 255
0 255 0
255 0 0
I presume you're going to apply a linear function to these colors to try to fade them out. This won't necessarily look as good as you think it might -- RGB as a representation isn't very linear. You can cheaply approximate a better "linear" representation by using an HSV or HSL representation instead. They surely aren't perfect but it will feel a little more natural than RGB.
As for mapping the IP address to a color, you could store these color combinations in an array and pick among the six elements by using a simple hash function. Something like this might be sufficient:
b1, b2, b3, b4 = <split the four bytes from an IP address>
index = (b1 * 17 + (b2 * 17 + (b3 * 17 + b4))) % 6
(I just picked the multiplier 17 out of the air -- its binary representation is 10001, which means the bits of each byte in the address get "smeared" over each other. There might be better values. Once you've gotten a few colors selected and a handful of IP addresses you can try changing the multiplier to e.g. 21 or 53 and see what makes most sense.)
Although this won't give you a result where one of {R,G,B} is always 0, a HSL representation might look good. As an example, let hue be a decimal value from 0 to 1, defined by
(float)(octet[0] + octet[1] << 8 + octet[2] << 16 + octet[3] << 24) / (2^32-1)
, where each octet[i] is an unsigned byte, and ^ is exponentiation). And then perhaps set lightness and saturation by hand, as per your preference. Just an idea!
As an added bonus, this makes fading the colours easy (just subtract some portion of "time" from saturation/lightness).
are you using a database to store the relations? you could always grab the user's IP Address
<?php
function userIP(){
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$userIp=$_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$userIp=$_SERVER['REMOTE_ADDR'];
}
return trim($userIp);
}
?>
Then use the function to set a usable variable of the IP:
<?php
$Users_IP_address = userIP();
?>
once you have that, you can assign a color that isn't in use and save the association for future reference.

PHP URL Shortening Algorithm

Could anyone recommend a preferred algorithm to use for URL shortening? I'm coding using PHP. Initially I thought about writing something that would start at a character such as "a" and iterate through requests, creating records in a database and therefore having to increment the character to b, c, d ... A, B and so on as appropriate.
However it dawned on me that this algorithm could be pretty heavy/clumsy and there could be a better way to do it.
I read around a bit on Google and some people seem to be doing it with base conversion from the database's ID column. This isn't something I'm too familiar with.
Could someone elaborate and explain to me how this would work? A couple of code examples would be great, too.
I obviously don't want a complete solution as I would like to learn by doing it myself, but just an explanation/pseudo-code on how this would work would be excellent.
Most shortening services just use a counter that is incremented with every entry and convert the base from 10 to 64.
An implementation in PHP could look like this:
function encode($number) {
return strtr(rtrim(base64_encode(pack('i', $number)), '='), '+/', '-_');
}
function decode($base64) {
$number = unpack('i', base64_decode(str_pad(strtr($base64, '-_', '+/'), strlen($base64) % 4, '=')));
return $number[1];
}
$number = mt_rand(0, PHP_INT_MAX);
var_dump(decode(encode($number)) === $number);
The encode function takes an integer number, converts it into bytes (pack), encodes it with the Base-64 encoding (base64_encode), trims the trailing padding = (rtrim), and replaces the characters + and / by - and _ respectively (strtr). The decode function is the inverse function to encode and does the exact opposite (except adding trailing padding).
The additional use of strtr is to translate the original Base-64 alphabet to the URL and filename safe alphabet as + and / need to be encoded with the Percentage-encoding.
You can use base_convert function to do a base convertion from 10 to 36 with the database IDs.
<?php
$id = 315;
echo base_convert($id, 10, 36), "\n";
?>
Or you can reuse some of the ideas presented in the comments on the page bellow:
http://php.net/manual/en/function.base-convert.php
Assuming your PRIMARY KEY is an INT and it auto_increments, the following code will get you going =).
<?php
$inSQL = "INSERT INTO short_urls() VALUES();";
$inResult = mysql_query($inSQL);
$databaseID = base_convert(mysql_insert_id(), 10, 36);
// $databaseID is now your short URL
?>
EDIT: Included the base_convert from HGF's answer. I forgot to base_convert in the original post.
i used to break ID by algorithm similar with how to convert from decimal to hex, but it will use 62 character instead of 16 character that hex would use.
'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
example : if you will change ID = 1234567890 you will get kv7yl1 as your a key.
I adopted a "light" solution. On user request I generate a unique identifier (checking for conflicts in db) with this python snipplet:
url_hash = base64.b64encode(os.urandom(int(math.ceil(0.75*7))))[:6]
and store it in db.
The native PHP base_convert() works well for small ranges of numbers, but if you really need to encode large values, consider using something like the implementation provided here which will work to base 64 and beyond if you simply provide more legal characters for the encoding.
http://af-design.com/blog/2010/08/10/working-with-big-integers-in-php/
Here try this method :
hash_hmac('joaat', "http://www.example.com/long/url/", "secretkey");
It will provide you with hash value fit for a professional url shortener, e.g: '142ecd53'

Categories