clrghouz/app/helpers.php

188 lines
3.7 KiB
PHP

<?php
/**
* Calculate CCITT-CRC16 checksum
*/
use Carbon\Carbon;
use Illuminate\Support\Collection;
if (! function_exists('crc16')) {
function crc16($data): int
{
$crc = 0x0000;
for ($i = 0; $i < strlen($data); $i++) {
$x = (($crc >> 8) ^ ord($data[$i])) & 0xFF;
$x ^= $x >> 4;
$crc = (($crc << 8) ^ ($x << 12) ^ ($x << 5) ^ $x) & 0xFFFF;
}
return $crc;
}
}
/**
* Dump out data into a hex dump
*/
if (! function_exists('hex_dump')) {
function hex_dump($data,$newline="\n",$width=16): string
{
$result = '';
$pad = '.'; # padding for non-visible characters
$to = $from = '';
for ($i=0; $i<=0xFF; $i++) {
$from .= chr($i);
$to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
}
$hex = str_split(bin2hex($data),$width*2);
$chars = str_split(strtr($data,$from,$to),$width);
$offset = 0;
foreach ($hex as $i => $line) {
$result .= sprintf('%08X: %-48s [%s]%s',
$offset,
substr_replace(implode(' ',str_split($line,2)),' ',8*3,0),
$chars[$i],
$newline);
$offset += $width;
}
return $result;
}
}
/**
* Send a value has hex chars
*/
if (! function_exists('hexstr')) {
function hexstr(int $int): string
{
if ($int > 0xffff)
throw new Exception('Int too large for hexstr');
$hexdigitslower = '0123456789abcdef';
$x = '';
if ($int > 0xff) {
$x .= substr($hexdigitslower,($int&0xf000)>>12,1);
$x .= substr($hexdigitslower,($int&0x0f00)>>8,1);
}
$x .= substr($hexdigitslower,($int&0x00f0)>>4,1);
$x .= substr($hexdigitslower,($int&0x000f),1);
return $x;
}
}
if (! function_exists('timew')) {
/**
* Convert a time into an 32 bit value. This is primarily used to create 8 character hex filenames that
* are unique using 1/10th second precision.
*
* Time is:
* + 02 bits unused
* + 04 bits Month
* + 05 bits Day
* + 05 bits Hour
* + 06 bits Min
* + 06 bits Sec
* + 04 bits 10th Sec
* = 32 (2 bits free)
*
* @param Carbon|null $time
* @return int
*/
function timew(Carbon $time=NULL): int
{
static $delay = 0;
// If we are not passed a time, we'll use the time now
if (! $time) {
// In case we are called twice, we'll delay 1/10th second so we have a unique result.
if (Carbon::now()->getPreciseTimestamp(1) === $delay)
usleep(100000);
$time = Carbon::now();
}
$delay = $time->getPreciseTimestamp(1);
$t = ($time->month & 0xf) << 5;
$t = ($t | ($time->day & 0x1f)) << 5;
$t = ($t | ($time->hour & 0x1f)) << 6;
$t = ($t | ($time->minute & 0x3f)) << 6;
$t = ($t | ($time->second & 0x3f));
return hexdec(sprintf('%07x%1x',$t,(round($time->milli/100) & 0x7f)));
}
}
if (! function_exists('dwtime')) {
/**
* Convert a 40 bit integer into a time.
* @see timew()
*
* @param int $time
* @param int|null $year
* @return Carbon
*/
function wtime(int $time,int $year=NULL): Carbon
{
if (! $year)
$year = Carbon::now()->year;
// Does the time have milli seconds?
if ($time > pow(2,26)-1) {
$milli = ($time & 0xf);
$time = $time >> 4;
} else {
$milli = 0;
}
$sec = ($time & 0x3f);
$time = $time >> 6;
$min = ($time & 0x3f);
$time = $time >> 6;
$hr = ($time & 0x1f);
$time = $time >> 5;
$day = ($time & 0x1f);
$time = $time >> 5;
$month = ($time & 0x1f);
return Carbon::create($year,$month,$day,$hr,$min,$sec+$milli/10);
}
}
if (! function_exists('optimize_path')) {
/**
* This will optimize an array of paths to show the smallest number of characters
*/
function optimize_path(Collection $path): Collection
{
$cur = NULL;
$result = collect();
foreach ($path as $address) {
[$host,$node] = explode('/',$address);
if ($host !== $cur) {
$cur = $host;
$result->push($address);
} else {
$result->push($node);
}
}
return $result;
}
}