mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-23 19:31:44 +00:00
Improved random number generation (lacking the Windows implementation which will come next).
This commit is contained in:
parent
b53de99588
commit
432d6a3596
@ -60,6 +60,7 @@ using namespace libebml;
|
||||
#include "error.h"
|
||||
#include "hacks.h"
|
||||
#include "mm_io.h"
|
||||
#include "random.h"
|
||||
|
||||
int verbose = 1;
|
||||
bool suppress_warnings = false;
|
||||
@ -185,10 +186,7 @@ bitvalue_c::data()
|
||||
|
||||
void
|
||||
bitvalue_c::generate_random() {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bitsize / 8; i++)
|
||||
value[i] = (unsigned char)(255.0 * rand() / RAND_MAX);
|
||||
random_c::generate_bytes(value, bitsize / 8);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -597,7 +595,6 @@ init_cc_stdio() {
|
||||
*/
|
||||
|
||||
static vector<uint32_t> ru_numbers[4];
|
||||
static bool random_seeded = false;
|
||||
|
||||
void
|
||||
clear_list_of_unique_uint32(unique_id_category_e category) {
|
||||
@ -661,7 +658,7 @@ remove_unique_uint32(uint32_t number,
|
||||
|
||||
uint32_t
|
||||
create_unique_uint32(unique_id_category_e category) {
|
||||
uint32_t rnumber, half;
|
||||
uint32_t rnumber;
|
||||
|
||||
assert((category >= UNIQUE_TRACK_IDS) &&
|
||||
(category <= UNIQUE_ATTACHMENT_IDS));
|
||||
@ -671,16 +668,8 @@ create_unique_uint32(unique_id_category_e category) {
|
||||
return ru_numbers[category].size();
|
||||
}
|
||||
|
||||
if (!random_seeded) {
|
||||
srand(time(NULL));
|
||||
random_seeded = true;
|
||||
}
|
||||
|
||||
do {
|
||||
half = (uint32_t)(65535.0 * rand() / RAND_MAX);
|
||||
rnumber = half;
|
||||
half = (uint32_t)(65535.0 * rand() / RAND_MAX);
|
||||
rnumber |= (half << 16);
|
||||
rnumber = random_c::generate_32bits();
|
||||
} while ((rnumber == 0) || !is_unique_uint32(rnumber, category));
|
||||
add_unique_uint32(rnumber, category);
|
||||
|
||||
|
118
src/common/random.cpp
Normal file
118
src/common/random.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
Distributed under the GPL
|
||||
see the file COPYING for details
|
||||
or visit http://www.gnu.org/copyleft/gpl.html
|
||||
|
||||
$Id$
|
||||
|
||||
random number generating functions
|
||||
|
||||
Written by Moritz Bunkus <moritz@bunkus.org>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#if !defined(SYS_WINDOWS)
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
#include "mm_io.h"
|
||||
#include "random.h"
|
||||
|
||||
#if defined(SYS_WINDOWS)
|
||||
|
||||
#else // defined(SYS_WINDOWS)
|
||||
|
||||
bool random_c::m_seeded = false;
|
||||
auto_ptr<mm_file_io_c> random_c::m_dev_urandom;
|
||||
bool random_c::m_tried_dev_urandom = false;
|
||||
|
||||
void
|
||||
random_c::generate_bytes(void *destination,
|
||||
int num_bytes) {
|
||||
int i;
|
||||
|
||||
try {
|
||||
if (!m_tried_dev_urandom) {
|
||||
m_tried_dev_urandom = true;
|
||||
m_dev_urandom =
|
||||
auto_ptr<mm_file_io_c>(new mm_file_io_c("/dev/urandom", MODE_READ));
|
||||
}
|
||||
if ((NULL != m_dev_urandom.get()) &&
|
||||
(m_dev_urandom->read(destination, num_bytes) == num_bytes))
|
||||
return;
|
||||
} catch(...) {
|
||||
}
|
||||
|
||||
if (!m_seeded) {
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
srand(tv.tv_usec + tv.tv_sec);
|
||||
m_seeded = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_bytes; ++i)
|
||||
((unsigned char *)destination)[i] =
|
||||
(unsigned char)(256.0 * rand() / (RAND_MAX + 1.0));
|
||||
}
|
||||
|
||||
#endif // defined(SYS_WINDOWS)
|
||||
|
||||
void
|
||||
random_c::test() {
|
||||
uint32_t n, ranges[16], i, k;
|
||||
const int num = 1000000;
|
||||
bool found;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
ranges[i] = 0;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
n = random_c::generate_32bits();
|
||||
found = false;
|
||||
for (k = 1; k <= 15; ++k)
|
||||
if (n < (k * 0x10000000)) {
|
||||
++ranges[k - 1];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
++ranges[15];
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
printf("%0d: %d (%.2f%%)\n", i, ranges[i],
|
||||
(double)ranges[i] * 100.0 / num);
|
||||
|
||||
#if !defined(SYS_WINDOWS)
|
||||
m_tried_dev_urandom = true;
|
||||
m_dev_urandom = auto_ptr<mm_file_io_c>(NULL);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
ranges[i] = 0;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
n = random_c::generate_32bits();
|
||||
found = false;
|
||||
for (k = 1; k <= 15; ++k)
|
||||
if (n < (k * 0x10000000)) {
|
||||
++ranges[k - 1];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
++ranges[15];
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
printf("%0d: %d (%.2f%%)\n", i, ranges[i],
|
||||
(double)ranges[i] * 100.0 / num);
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
}
|
78
src/common/random.h
Normal file
78
src/common/random.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
Distributed under the GPL
|
||||
see the file COPYING for details
|
||||
or visit http://www.gnu.org/copyleft/gpl.html
|
||||
|
||||
$Id$
|
||||
|
||||
definitions for random number generating functions
|
||||
|
||||
Written by Moritz Bunkus <moritz@bunkus.org>.
|
||||
*/
|
||||
|
||||
#ifndef __RANDOM_H
|
||||
#define __RANDOM_H
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "mm_io.h"
|
||||
#include "smart_pointers.h"
|
||||
|
||||
class MTX_DLL_API random_c {
|
||||
private:
|
||||
#if !defined(SYS_WINDOWS)
|
||||
static bool m_seeded;
|
||||
static auto_ptr<mm_file_io_c> m_dev_urandom;
|
||||
static bool m_tried_dev_urandom;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static void generate_bytes(void *destination, int num_bytes);
|
||||
|
||||
static uint8_t generate_8bits() {
|
||||
uint8_t b;
|
||||
|
||||
generate_bytes(&b, 1);
|
||||
return b;
|
||||
}
|
||||
|
||||
static int16_t generate_15bits() {
|
||||
return (int16_t)(generate_16bits() & 0x7fff);
|
||||
}
|
||||
|
||||
static uint16_t generate_16bits() {
|
||||
uint16_t b;
|
||||
|
||||
generate_bytes(&b, 2);
|
||||
return b;
|
||||
}
|
||||
|
||||
static int32_t generate_31bits() {
|
||||
return (int32_t)(generate_32bits() & 0x7fffffff);
|
||||
}
|
||||
|
||||
static uint32_t generate_32bits() {
|
||||
uint32_t b;
|
||||
|
||||
generate_bytes(&b, 4);
|
||||
return b;
|
||||
}
|
||||
|
||||
static int64_t generate_63bits() {
|
||||
return (int64_t)(generate_64bits() & 0x7fffffffffffull);
|
||||
}
|
||||
|
||||
static uint64_t generate_64bits() {
|
||||
uint64_t b;
|
||||
|
||||
generate_bytes(&b, 8);
|
||||
return b;
|
||||
}
|
||||
|
||||
static void test();
|
||||
};
|
||||
|
||||
#endif // __RANDOM_H
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "commonebml.h"
|
||||
#include "random.h"
|
||||
|
||||
#include "xtr_ogg.h"
|
||||
|
||||
@ -61,7 +62,7 @@ xtr_oggbase_c::create_file(xtr_base_c *_master,
|
||||
if (no_variable_data)
|
||||
ogg_stream_init(&os, 1804289383);
|
||||
else
|
||||
ogg_stream_init(&os, rand());
|
||||
ogg_stream_init(&os, random_c::generate_31bits());
|
||||
}
|
||||
|
||||
void
|
||||
@ -172,7 +173,7 @@ xtr_oggflac_c::create_file(xtr_base_c *_master,
|
||||
if (no_variable_data)
|
||||
ogg_stream_init(&os, 1804289383);
|
||||
else
|
||||
ogg_stream_init(&os, rand());
|
||||
ogg_stream_init(&os, random_c::generate_31bits());
|
||||
|
||||
// Handle the three header packets: Headers, comments, codec
|
||||
// setup data.
|
||||
|
@ -1947,7 +1947,6 @@ setup() {
|
||||
#endif
|
||||
|
||||
mm_file_io_c::setup();
|
||||
srand(time(NULL));
|
||||
cc_local_utf8 = utf8_init("");
|
||||
init_cc_stdio();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user