From c7bab7cbf5d6a8b442f2ed3e23543cb4ee826c87 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 31 Aug 2016 15:01:08 -0700 Subject: [PATCH] Issue #27706: Fix regression in random.seed(somestr, version=1) --- Lib/random.py | 7 +++++++ Lib/test/test_random.py | 18 ++++++++++++++++++ Misc/NEWS | 5 +++++ 3 files changed, 30 insertions(+) diff --git a/Lib/random.py b/Lib/random.py index 5950735e3ee..06513c824f8 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -112,6 +112,13 @@ class Random(_random.Random): import time a = int(time.time() * 256) # use fractional seconds + if version == 1 and isinstance(a, (str, bytes)): + x = ord(a[0]) << 7 if a else 0 + for c in a: + x = ((1000003 * x) ^ ord(c)) & 0xFFFFFFFFFFFFFFFF + x ^= len(a) + a = -2 if x == -1 else x + if version == 2: if isinstance(a, (str, bytes, bytearray)): if isinstance(a, str): diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index 5393431ff65..e80ed17a8cb 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -326,6 +326,24 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase): ['0x1.1239ddfb11b7cp-3', '0x1.b3cbb5c51b120p-4', '0x1.8c4f55116b60fp-1', '0x1.63eb525174a27p-1']) + def test_bug_27706(self): + # Verify that version 1 seeds are unaffected by hash randomization + + self.gen.seed('nofar', version=1) # hash('nofar') == 5990528763808513177 + self.assertEqual([self.gen.random().hex() for i in range(4)], + ['0x1.8645314505ad7p-1', '0x1.afb1f82e40a40p-5', + '0x1.2a59d2285e971p-1', '0x1.56977142a7880p-6']) + + self.gen.seed('rachel', version=1) # hash('rachel') == -9091735575445484789 + self.assertEqual([self.gen.random().hex() for i in range(4)], + ['0x1.0b294cc856fcdp-1', '0x1.2ad22d79e77b8p-3', + '0x1.3052b9c072678p-2', '0x1.578f332106574p-3']) + + self.gen.seed('', version=1) # hash('') == 0 + self.assertEqual([self.gen.random().hex() for i in range(4)], + ['0x1.b0580f98a7dbep-1', '0x1.84129978f9c1ap-1', + '0x1.aeaa51052e978p-2', '0x1.092178fb945a6p-2']) + def test_setstate_first_arg(self): self.assertRaises(ValueError, self.gen.setstate, (1, None, None)) diff --git a/Misc/NEWS b/Misc/NEWS index 129e124c928..731685fd930 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -55,6 +55,11 @@ Library - Issue #19884: Avoid spurious output on OS X with Gnu Readline. +- Issue #27706: Restore deterministic behavior of random.Random().seed() + for string seeds using seeding version 1. Allows sequences of calls + to random() to exactly match those obtained in Python 2. + Patch by Nofar Schnider. + - Issue #10513: Fix a regression in Connection.commit(). Statements should not be reset after a commit.