2 * Copyright 2013 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
16 static const char* const kHexChars
= "0123456789abcdef";
18 static const size_t kVersionByteIndex
= 6;
19 static const size_t kVariantByteIndex
= 8;
25 // set a time-based seed
27 clock_gettime(CLOCK_REALTIME
, &time
);
28 uint32 seed
= (uint32
)time
.tv_sec
^ (uint32
)time
.tv_nsec
;
30 // factor in a stack address -- with address space layout randomization
31 // that adds a bit of additional randomness
32 seed
^= (uint32
)(addr_t
)&time
;
44 memset(fValue
, 0, sizeof(fValue
));
48 BUuid::BUuid(const BUuid
& other
)
50 memcpy(fValue
, other
.fValue
, sizeof(fValue
));
62 for (size_t i
= 0; i
< sizeof(fValue
); i
++) {
74 if (!BUuid::_SetToDevRandom())
75 BUuid::_SetToRandomFallback();
77 // set variant and version
78 fValue
[kVariantByteIndex
] &= 0x3f;
79 fValue
[kVariantByteIndex
] |= 0x80;
80 fValue
[kVersionByteIndex
] &= 0x0f;
81 fValue
[kVersionByteIndex
] |= 4 << 4;
89 BUuid::ToString() const
92 for (size_t i
= 0; i
< 16; i
++) {
93 buffer
[2 * i
] = kHexChars
[fValue
[i
] >> 4];
94 buffer
[2 * i
+ 1] = kHexChars
[fValue
[i
] & 0xf];
97 return BString().SetToFormat("%.8s-%.4s-%.4s-%.4s-%.12s",
98 buffer
, buffer
+ 8, buffer
+ 12, buffer
+ 16, buffer
+ 20);
103 BUuid::Compare(const BUuid
& other
) const
105 return memcmp(fValue
, other
.fValue
, sizeof(fValue
));
110 BUuid::operator=(const BUuid
& other
)
112 memcpy(fValue
, other
.fValue
, sizeof(fValue
));
119 BUuid::_SetToDevRandom()
122 int fd
= open("/dev/urandom", O_RDONLY
);
124 fd
= open("/dev/random", O_RDONLY
);
130 ssize_t bytesRead
= read(fd
, fValue
, sizeof(fValue
));
133 return bytesRead
== (ssize_t
)sizeof(fValue
);
138 BUuid::_SetToRandomFallback()
140 static bool sSeedInitialized
= init_random_seed();
141 (void)sSeedInitialized
;
143 for (int32 i
= 0; i
< 4; i
++) {
144 uint32 value
= random();
145 fValue
[4 * i
+ 0] = uint8(value
>> 24);
146 fValue
[4 * i
+ 1] = uint8(value
>> 16);
147 fValue
[4 * i
+ 2] = uint8(value
>> 8);
148 fValue
[4 * i
+ 3] = uint8(value
);
151 // random() returns 31 bit numbers only, so we move a few bits from where
152 // we overwrite them with the version anyway.
153 uint8 bitsToMove
= fValue
[kVersionByteIndex
];
154 for (int32 i
= 0; i
< 4; i
++)
155 fValue
[4 * i
] |= (bitsToMove
<< i
) & 0x80;
158 } // namespace BPrivate
161 using BPrivate::BUuid
;