note 92952 deleted from function.hexdec by danbrown
| From: | danbrown@php.net | Date: | Thu, 06 May 2010 15:46:58 +0000 |
| Subject: | note 92952 deleted from function.hexdec by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-169017@lists.php.net to get a copy of this message | ||
Note Submitter: jose dot rob dot jr at gmail dot com
----
I made these functions to pack up to 64 ID's into a mysql unsigned bigint.
ID's cannot repeat, must be <= bit's limit and > 0.
The functions uses php 32 bit's int as unsigned because we don't actually read the number,
just the bits. Then 0xFFFFFFFF display -1 but the bit's are there (tested with linux 2.6 i686
and x86_64)
<?php
define('LIMIT', 1); // 1 = 32 bits; 2 = 64 bits; 3 = 96 bits...
// ids cannot repeat and must be <= number of bits and >= 1
function hex_ids($id_ary, $include_x = false)
{
$ints = array_fill(0, LIMIT, 0);
foreach($id_ary as $id)
{
$k = intval($id / 32);
$k -= ($id % 32? 0 : 1);
$b = $id - (32 * $k) - 1;
if(false)
{ // This limit to LIMIT * 32 bits
if(!isset($ints[$k]))
{
trigger_error('Too long number! 1 << ' . ($id-1), E_USER_ERROR);
}
}
elseif($k > 0)
{
// This adds 32 bits, you choose
// to make infinity, make this block reachable changing if condition up there
// false = infinity, true = limited
$ints += array_fill(0, $k, 0);
}
$ints[$k] |= 1 << $b;
}
$hex = '';
$ints = array_reverse($ints);
foreach($ints as $i)
{
$hex .= sprintf('%08X',$i);
}
return (!$include_x? $hex : "0x$hex");
}
function get_ids($hex, $convert = false)
{
if($convert || is_int($hex) || is_float($hex))
{
$hex = dechex($hex);
}
$hex = preg_replace('/^(0x|X)?0*/i', '', $hex);
$hex = preg_replace('/\b/', '', $hex);
$hex = array_reverse(str_split($hex));
$ids = array();
foreach($hex as $k=>$n)
{
$n = (int) hexdec($n);
for($j = 1, $s = 1; $j <= 8; $j <<= 1, $s++)
{
if($n & $j)
{
$ids[] = (4 * $k) + $s;
}
}
}
return $ids;
}
// Our friend's function is helpfull :-)
if(!function_exists('bchexdec'))
{
function bchexdec()
{
echo '<a href="http://br2.php.net/manual/en/function.hexdec.php#90309"
style="text-decoration: none">This function is available
here</a><br/>';
}
}
// Tests
echo "<b>Debug:</b> <pre>";
// 32 bits
$ids = range(1, 32, 1);
echo '32 bits: <br/>';
var_dump($hex = hex_ids($ids)); // string(8) "FFFFFFFF"
var_dump(bchexdec($hex)); // string(10) "4294967295"
print_r(get_ids($hex)); // array([0] => 1 [1] => 2 ... [30] => 31 [31] => 32)
// 64 bits (with 0x)
$ids = range(1, 64, 1);
echo '64 bits with 0x: <br/>';
var_dump($hex = hex_ids($ids, true)); // string(18) "0xFFFFFFFFFFFFFFFF"
var_dump(bchexdec($hex)); // string(20) "18446744073709551615"
print_r(get_ids($hex)); // array([0] => 1 [1] => 2 ... [62] => 63 [63] => 64)
// random bits from 32 to 256 and random ids
$ids = array();
$x = rand(32, 256);
for($i = 0; $i < rand(10,$x); $i++)
{
while(in_array($n = rand(1, $x), $ids))
{
}
$ids[] = $n;
}
echo 'Random up to 256 bits and with 0x: <br/>';
// spaces added below because the number is too long
print_r($ids);
// array( [1] => 64 ... [8] => 48 ... [11] => 240 ... [16] => 229 )
var_dump($hex = hex_ids($ids, true));
// string(64) "0000 8010 6408 0011 2400 0000 0800 0004 8040 0000 0000 4009 8000 8000 0000
0000"
var_dump(bchexdec($hex));
// string(72) "883 865 426 056 150 138 836 378 456 722 453 625 184 209 548 165 513 401 329 718
849 844 543 488"
print_r(get_ids($hex));
// array([0] => 48, [1] => 64 ... [17] => 229 [18] => 240)
die("\n<br>debug");
?>
Here's my contribution
I hope this help you :D