File indexing completed on 2024-05-12 15:58:39
0001 /* 0002 * This file is part of the KDE project 0003 * 0004 * SPDX-FileCopyrightText: 2008, 2009 Cyrille Berger <cberger@cberger.net> 0005 * SPDX-FileCopyrightText: 2009 Matthew Woehlke <mw_triad@users.sourceforge.net> 0006 * 0007 * SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "kis_random_generator.h" 0011 0012 /* Mac OS X doesn't define a number of UINT* macros without this before stdlib.h */ 0013 #define __STDC_LIMIT_MACROS 0014 0015 #include <stdlib.h> 0016 #include <stdint.h> 0017 #include <math.h> 0018 0019 #include "rand_salt.h" 0020 0021 inline quint64 permuteWhole(quint64 n, quint64 a, quint64 b) 0022 { 0023 return ((n * a) + b); 0024 } 0025 0026 inline quint64 part(quint64 n1, quint64 n2, int p) 0027 { 0028 int b = p * 8; 0029 int i = (n1 >> b) & 0xFF; 0030 int j = (n2 >> b) & 0xFF; 0031 return quint64(salt[i][j]) << b; 0032 } 0033 0034 struct Q_DECL_HIDDEN KisRandomGenerator::Private { 0035 quint64 seed; 0036 }; 0037 0038 KisRandomGenerator::KisRandomGenerator(quint64 seed) : d(new Private) 0039 { 0040 d->seed = seed; 0041 } 0042 0043 KisRandomGenerator::~KisRandomGenerator() 0044 { 0045 delete d; 0046 } 0047 0048 quint64 KisRandomGenerator::randomAt(qint64 x, qint64 y) 0049 { 0050 const quint64 kxa = 427140578808118991LL; 0051 const quint64 kya = 166552399647317237LL; 0052 const quint64 kxb = 48058817213113801LL; 0053 const quint64 kyb = 9206429469018994469LL; 0054 0055 // Generate salts 0056 quint64 n1 = (quint64(x + 5) * kxa) * d->seed; 0057 quint64 n2 = (quint64(y + 7) * kya) + (d->seed * 1040097393733LL); 0058 n1 = permuteWhole(n1, 8759824322359LL, 13); 0059 n2 = permuteWhole(n2, 200560490131LL, 2707); 0060 n1 = (n1 >> 32) ^ (n1 << 32); 0061 n2 = (n2 >> 32) ^ (n2 << 32); 0062 n1 ^= x ^ (quint64(y ^ d->seed) * kyb); 0063 n2 ^= y ^ (quint64(x + 13) * kxb); 0064 0065 // Combine salts 0066 quint64 v = 0; 0067 for (int p = 0; p < 8; ++p) 0068 v |= part(n1, n2, p); 0069 return v; 0070 } 0071 0072 double KisRandomGenerator::doubleRandomAt(qint64 x, qint64 y) 0073 { 0074 return randomAt(x, y) / (double)UINT64_MAX; 0075 } 0076