diff options
Diffstat (limited to 'libavutil/random_seed.c')
-rw-r--r-- | libavutil/random_seed.c | 73 |
1 files changed, 51 insertions, 22 deletions
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c index 089d883916..881c23c8c8 100644 --- a/libavutil/random_seed.c +++ b/libavutil/random_seed.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -23,6 +23,9 @@ #if HAVE_UNISTD_H #include <unistd.h> #endif +#if HAVE_IO_H +#include <io.h> +#endif #if HAVE_WINCRYPT #include <windows.h> #include <wincrypt.h> @@ -30,13 +33,18 @@ #include <fcntl.h> #include <math.h> #include <time.h> +#include <string.h> +#include "avassert.h" #include "internal.h" #include "intreadwrite.h" -#include "mem.h" #include "timer.h" #include "random_seed.h" #include "sha.h" +#ifndef TEST +#define TEST 0 +#endif + static int read_random(uint32_t *dst, const char *file) { #if HAVE_UNISTD_H @@ -56,39 +64,56 @@ static int read_random(uint32_t *dst, const char *file) static uint32_t get_generic_seed(void) { - struct AVSHA *sha = av_sha_alloc(); + uint64_t tmp[120/8]; + struct AVSHA *sha = (void*)tmp; clock_t last_t = 0; + clock_t last_td = 0; + clock_t init_t = 0; static uint64_t i = 0; static uint32_t buffer[512] = { 0 }; unsigned char digest[20]; uint64_t last_i = i; + av_assert0(sizeof(tmp) >= av_sha_size); + + if(TEST){ + memset(buffer, 0, sizeof(buffer)); + last_i = i = 0; + }else{ +#ifdef AV_READ_TIME + buffer[13] ^= AV_READ_TIME(); + buffer[41] ^= AV_READ_TIME()>>32; +#endif + } + for (;;) { clock_t t = clock(); - - if (last_t == t) { - buffer[i & 511]++; + if (last_t + 2*last_td + (CLOCKS_PER_SEC > 1000) >= t) { + last_td = t - last_t; + buffer[i & 511] = 1664525*buffer[i & 511] + 1013904223 + (last_td % 3294638521U); } else { - buffer[++i & 511] += (t - last_t) % 3294638521U; - if (last_i && i - last_i > 4 || i - last_i > 64) - break; + last_td = t - last_t; + buffer[++i & 511] += last_td % 3294638521U; + if ((t - init_t) >= CLOCKS_PER_SEC>>5) + if (last_i && i - last_i > 4 || i - last_i > 64 || TEST && i - last_i > 8) + break; } last_t = t; + if (!init_t) + init_t = t; } - if (!sha) { - uint32_t seed = 0; - int j; - // Unable to allocate an SHA context, just XOR the buffer together - // to create something hopefully unique. - for (j = 0; j < 512; j++) - seed ^= buffer[j]; - return seed; + if(TEST) { + buffer[0] = buffer[1] = 0; + } else { +#ifdef AV_READ_TIME + buffer[111] += AV_READ_TIME(); +#endif } + av_sha_init(sha, 160); - av_sha_update(sha, (const uint8_t *) buffer, sizeof(buffer)); + av_sha_update(sha, (const uint8_t *)buffer, sizeof(buffer)); av_sha_final(sha, digest); - av_free(sha); return AV_RB32(digest) + AV_RB32(digest + 16); } @@ -107,6 +132,10 @@ uint32_t av_get_random_seed(void) } #endif +#if HAVE_ARC4RANDOM + return arc4random(); +#endif + if (read_random(&seed, "/dev/urandom") == sizeof(seed)) return seed; if (read_random(&seed, "/dev/random") == sizeof(seed)) |