Skip to content

Instantly share code, notes, and snippets.

@derrekbertrand
Created March 18, 2018 04:52
Show Gist options
  • Save derrekbertrand/6eae3867954531ad79bf90a1494d6aa9 to your computer and use it in GitHub Desktop.
Save derrekbertrand/6eae3867954531ad79bf90a1494d6aa9 to your computer and use it in GitHub Desktop.
<?php
/*
* Copyright 2017-2018 Derrek Bertrand <[email protected]>
* Copyright 2018 CollabCorp Group
*
* License: MIT
*/
use Exception;
/**
* Small UUID v4 Class
*
* Requires:
* - A 64 bit PHP runtime
* - Probably a little endian system
* - PHP 7+
*/
class Uuid4
{
protected $value = null;
public function __construct($value = null)
{
// This implementation only runs on a 64 bit system!
// Although, it is set up to at least have the possibility of being
// ported to other architectures.
if (PHP_INT_SIZE !== 8) {
throw new Exception('Uuid4 only runs on 64 bit systems!');
}
// set the value if provided, otherwise do nothing
if ($value !== null) {
$this->setValue($value);
}
}
/**
* Returns the value as a base 64 string.
*
* @return string
*/
public function getBase64()
{
return base64_encode($this->getBytes());
}
/**
* Returns the value as a binary string; generates one if not set.
*
* @return string
*/
public function getBytes()
{
return $this->value ?? $this->setValue()->value;
}
/**
* Returns the value as a hexadecimal string.
*
* @return string
*/
public function getHex()
{
return bin2hex($this->getBytes());
}
/**
* Returns the value as a UUIDv4-style string.
*
* @return string
*/
public function getUuidV4()
{
return implode('-', unpack('H8a/H4b/H4c/H4d/H12e', $this->getBytes()));
}
/**
* Set or generate a new Ksuid.
*
* @param mixed $value
* @return $this
*/
public function setValue($value = null)
{
if ($value === null) {
// no value is provided, generate one
$pack = unpack('H8a/H4b/nc/nd/H12e', random_bytes(16));
$pack['c'] = dechex($pack['c'] & 0x0fff | 0x4000); //UUID version
$pack['d'] = dechex($pack['d'] & 0x3fff | 0x8000); //reserved bits
$this->value = hex2bin(implode($pack));
} elseif ($value instanceof Ksuid) {
// set from another Ksuid
$this->value = $value->getBytes();
} elseif (is_string($value) && strlen($value) === 32 && preg_match('/[^0-9A-Fa-f]/', $value) === 0) {
// a hexadecimal value is provided
$this->value = hex2bin($value);
} else {
throw new Exception('Uuid4 only accepts hexadecimal strings when setting value.');
}
return $this;
}
/**
* Returns the value as a string.
*
* @return string
*/
public function __toString()
{
return $this->getBytes();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment