提交 ae76a3f6 编写于 作者: M Marvin Häuser

User: Introduce UserPseudoRadom

上级 ced62ddf
/** @file
Copyright (c) 2020, vit9696. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
**/
#ifndef OC_USER_PSEUDO_RANDOM_H
#define OC_USER_PSEUDO_RANDOM_H
#include <stdint.h>
uint32_t pseudo_random(void);
uint32_t pseudo_random_between(uint32_t from, uint32_t to);
#endif // OC_USER_PSEUDO_RANDOM_H
/** @file
Copyright (c) 2020, vit9696. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#ifdef __GNUC__
uint32_t arc4random(void) __attribute__((weak));
uint32_t arc4random_uniform(uint32_t upper_bound) __attribute__((weak));
#endif
// Taken from https://en.wikipedia.org/wiki/Xorshift#Example_implementation
// I am not positive what is better to use here (especially on Windows).
// Fortunately we only need something only looking random.
uint32_t pseudo_random(void) {
#if defined(__GNUC__) && !defined(__EMSCRIPTEN__)
if (arc4random)
return arc4random();
#endif
static uint32_t state;
if (!state) {
fprintf(stderr, "Warning: arc4random is not available!\n");
state = (uint32_t)time(NULL);
}
uint32_t x = state;
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
state = x;
return x;
}
// Taken from https://opensource.apple.com/source/Libc/Libc-1082.50.1/gen/FreeBSD/arc4random.c
// Mac OS X 10.6.8 and earlier do not have arc4random_uniform, so we implement one.
uint32_t pseudo_random_between(uint32_t from, uint32_t to) {
uint32_t upper_bound = to + 1 - from;
#if defined(__GNUC__) && !defined(__EMSCRIPTEN__)
// Prefer native implementation if available.
if (arc4random_uniform)
return from + arc4random_uniform(upper_bound);
#endif
uint32_t r, min;
if (upper_bound < 2)
return from;
#if (ULONG_MAX > 0xffffffffUL)
min = 0x100000000UL % upper_bound;
#else
if (upper_bound > 0x80000000)
min = 1 + ~upper_bound;
else
min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
#endif
for (;;) {
r = pseudo_random();
if (r >= min)
break;
}
return from + r % upper_bound;
}
......@@ -217,7 +217,7 @@ endif
# Miscellaneous implementations that do not depend on UDK.
#
VPATH += $(OC_USER)/User/Library:$
OBJS += UserFile.o
OBJS += UserFile.o UserPseudoRandom.o
#
# Directory where objects will be produced.
......
......@@ -18,6 +18,8 @@
#include <IOKit/IOKitLib.h>
#endif
#include <UserPseudoRandom.h>
#include "macserial.h"
#include "modelinfo.h"
......@@ -120,64 +122,6 @@ static bool verify_mlb_checksum(const char *mlb, size_t len) {
return checksum % (sizeof(alphabet) - 1) == 0;
}
// Taken from https://en.wikipedia.org/wiki/Xorshift#Example_implementation
// I am not positive what is better to use here (especially on Windows).
// Fortunately we only need something only looking random.
static uint32_t pseudo_random(void) {
#if defined(__GNUC__) && !defined(__EMSCRIPTEN__)
if (arc4random)
return arc4random();
#endif
static uint32_t state;
if (!state) {
fprintf(stderr, "Warning: arc4random is not available!\n");
state = (uint32_t)time(NULL);
}
uint32_t x = state;
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
state = x;
return x;
}
// Taken from https://opensource.apple.com/source/Libc/Libc-1082.50.1/gen/FreeBSD/arc4random.c
// Mac OS X 10.6.8 and earlier do not have arc4random_uniform, so we implement one.
static uint32_t pseudo_random_between(uint32_t from, uint32_t to) {
uint32_t upper_bound = to + 1 - from;
#if defined(__GNUC__) && !defined(__EMSCRIPTEN__)
// Prefer native implementation if available.
if (arc4random_uniform)
return from + arc4random_uniform(upper_bound);
#endif
uint32_t r, min;
if (upper_bound < 2)
return from;
#if (ULONG_MAX > 0xffffffffUL)
min = 0x100000000UL % upper_bound;
#else
if (upper_bound > 0x80000000)
min = 1 + ~upper_bound;
else
min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
#endif
for (;;) {
r = pseudo_random();
if (r >= min)
break;
}
return from + r % upper_bound;
}
static int32_t get_current_model(void) {
#ifdef __APPLE__
CFDataRef model = get_ioreg_entry("IODeviceTree:/", CFSTR("model"), CFDataGetTypeID());
......
......@@ -13,11 +13,6 @@
#define PROGRAM_VERSION "2.1.7"
#ifdef __GNUC__
uint32_t arc4random(void) __attribute__((weak));
uint32_t arc4random_uniform(uint32_t upper_bound) __attribute__((weak));
#endif
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define SZUUID 16
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册