mirror of
https://github.com/ramsey/uuid.git
synced 2026-06-14 15:56:48 +03:00
Merge branch 'master' into fix/replace-deprecated-getMock
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
# ramsey/uuid Changelog
|
||||
|
||||
## 3.7.1
|
||||
|
||||
* Use `random_bytes()` when generating random nodes
|
||||
* Set the multicast bit for random nodes, according to RFC 4122, §4.5, [#170](https://github.com/ramsey/uuid/pull/170), [#171](https://github.com/ramsey/uuid/pull/171), [#182](https://github.com/ramsey/uuid/pull/182)
|
||||
|
||||
## 3.7.0
|
||||
|
||||
_Released: 2017-08-04_
|
||||
|
||||
@@ -31,6 +31,11 @@ class RandomNodeProvider implements NodeProviderInterface
|
||||
*/
|
||||
public function getNode()
|
||||
{
|
||||
return sprintf('%06x%06x', mt_rand(0, 0xffffff), mt_rand(0, 0xffffff));
|
||||
$node = hexdec(bin2hex(random_bytes(6)));
|
||||
|
||||
// Set the multicast bit; see RFC 4122, section 4.5.
|
||||
$node = $node | 0x010000000000;
|
||||
|
||||
return str_pad(dechex($node), 12, '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,6 @@ use AspectMock\Test as AspectMock;
|
||||
|
||||
class RandomNodeProviderTest extends TestCase
|
||||
{
|
||||
private $num = 16532480;
|
||||
private $node = 'fc4400fc4400';
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->skipIfHhvm();
|
||||
@@ -27,36 +24,79 @@ class RandomNodeProviderTest extends TestCase
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testGetNodeUsesMtRand()
|
||||
public function testGetNodeUsesRandomBytes()
|
||||
{
|
||||
$mtRand = AspectMock::func('Ramsey\Uuid\Provider\Node', 'mt_rand', $this->num);
|
||||
$bytes = pack('H*', base_convert(decbin(3892974093781), 2, 16));
|
||||
|
||||
$randomBytes = AspectMock::func('Ramsey\Uuid\Provider\Node', 'random_bytes', $bytes);
|
||||
$provider = new RandomNodeProvider();
|
||||
$provider->getNode();
|
||||
$mtRand->verifyInvokedMultipleTimes(2, [0, 0xffffff]);
|
||||
$randomBytes->verifyInvoked(6);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testGetNodeFormatsRandomNumbersIntoHexString()
|
||||
public function testGetNodeSetsMulticastBit()
|
||||
{
|
||||
AspectMock::func('Ramsey\Uuid\Provider\Node', 'mt_rand', $this->num);
|
||||
$sprintf = AspectMock::func('Ramsey\Uuid\Provider\Node', 'sprintf', $this->node);
|
||||
$bytes = pack('H*', base_convert(decbin(3892974093781), 2, 16));
|
||||
$expectedBytesHex = '38a675685d50';
|
||||
$decimal = 62287585500496;
|
||||
$expectedNode = '39a675685d50';
|
||||
|
||||
AspectMock::func('Ramsey\Uuid\Provider\Node', 'random_bytes', $bytes);
|
||||
$hexDec = AspectMock::func('Ramsey\Uuid\Provider\Node', 'hexdec', $decimal);
|
||||
$provider = new RandomNodeProvider();
|
||||
$provider->getNode();
|
||||
$sprintf->verifyInvoked(['%06x%06x', $this->num, $this->num]);
|
||||
|
||||
$this->assertSame($expectedNode, $provider->getNode());
|
||||
$hexDec->verifyInvoked($expectedBytesHex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testGetNodeReturnsHexString()
|
||||
public function testGetNodeAlreadyHasMulticastBit()
|
||||
{
|
||||
AspectMock::func('Ramsey\Uuid\Provider\Node', 'mt_rand', $this->num);
|
||||
AspectMock::func('Ramsey\Uuid\Provider\Node', 'sprintf', $this->node);
|
||||
$bytes = pack('H*', base_convert(decbin(4492974093781), 2, 16));
|
||||
$expectedBytesHex = '4161a1ff5d50';
|
||||
$decimal = 71887585500496;
|
||||
|
||||
// We expect the same hex value for the node.
|
||||
$expectedNode = $expectedBytesHex;
|
||||
|
||||
AspectMock::func('Ramsey\Uuid\Provider\Node', 'random_bytes', $bytes);
|
||||
$hexDec = AspectMock::func('Ramsey\Uuid\Provider\Node', 'hexdec', $decimal);
|
||||
$provider = new RandomNodeProvider();
|
||||
$this->assertEquals($this->node, $provider->getNode());
|
||||
|
||||
$this->assertSame($expectedNode, $provider->getNode());
|
||||
$hexDec->verifyInvoked($expectedBytesHex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testGetNodeSetsMulticastBitForLowNodeValue()
|
||||
{
|
||||
$bytes = pack('H*', base_convert(decbin(1), 2, 16));
|
||||
$expectedBytesHex = '10';
|
||||
$decimal = 16;
|
||||
$expectedNode = '010000000010';
|
||||
|
||||
AspectMock::func('Ramsey\Uuid\Provider\Node', 'random_bytes', $bytes);
|
||||
$hexDec = AspectMock::func('Ramsey\Uuid\Provider\Node', 'hexdec', $decimal);
|
||||
$provider = new RandomNodeProvider();
|
||||
|
||||
$this->assertSame($expectedNode, $provider->getNode());
|
||||
$hexDec->verifyInvoked($expectedBytesHex);
|
||||
}
|
||||
|
||||
public function testGetNodeAlwaysSetsMulticastBit()
|
||||
{
|
||||
$provider = new RandomNodeProvider();
|
||||
|
||||
$this->assertSame('010000000000', sprintf('%012x', hexdec($provider->getNode()) & 0x010000000000));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user