diff --git a/Random/.generators.py.swp b/Random/.generators.py.swp
deleted file mode 100644
index af74f0d2fd905306d364547cccd8084cc04b07d5..0000000000000000000000000000000000000000
Binary files a/Random/.generators.py.swp and /dev/null differ
diff --git a/Random/__pycache__/generators.cpython-36.pyc b/Random/__pycache__/generators.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..12d1299222c60aedbec5e87efed307976b0ef7b8
Binary files /dev/null and b/Random/__pycache__/generators.cpython-36.pyc differ
diff --git a/Random/generators.py b/Random/generators.py
index 3534eadbe9fd6930a256f9f985dbf1d23dd440d0..2d8a444ca88107b4134734a5fee61a5a36971de1 100644
--- a/Random/generators.py
+++ b/Random/generators.py
@@ -1,37 +1,188 @@
 ## Various Random Generators ##
+import random
+
 
 class RandomNumberGenerator:
     def __init__(self):
         return NotImplementedError
 
-    def random():
+    def random(self):
         """
         yield a number from the RNG
         """
         return NotImplementedError
-    
-    def seed():
+
+    def seed(self):
         """
         set the seed of the generator
         """
         return NotImplementedError
 
+    def randomNorm(self):
+        """
+        return random between 0 and 1
+        """
+        return NotImplementedError
+
+    def batchRandomNormalized(self, n):
+        """
+        return n normalized values
+        """
+        return [self.randomNorm() for i in range(n)]
+
 
 class LCG(RandomNumberGenerator):
     """
     Linear Congruential generator algorithm
     """
 
-    def __init__(self, m, c, a):
+    def __init__(self, a, c, m):
         super().__init__()
         self.m = m
         self.c = c
         self.a = a
-        self.x = 0 #default seed
+        self.x = 0  # default seed
+
+    def random(self):
+        self.x = (self.a * self.x + self.c) % self.m
+        return self.x
+
+    def seed(self, seed):
+        self.x = seed
+
+    def randomNorm(self):
+        return self.random() / (self.m + 1)
 
-    def random():
-        self.x = self.a * self.x + self.c % self.m
+
+class ParkMiller(LCG):
+    """
+    Park and Miller's LCG
+    """
+
+    def __init__(self):
+        super().__init__(16807, 0, 2147483647)
+
+
+class KnuthLewis(LCG):
+    """
+    Knuth and Lewis' LCG
+    """
+
+    def __init__(self):
+        super().__init__(1664525, 1013904223, 4294967296)
+
+
+class Marsaglia(LCG):
+    """
+    Marsaglia's LCG
+    """
+
+    def __init__(self):
+        super().__init__(69069, 0, 4294967296)
+
+
+class LavauxJenssens(LCG):
+    """
+    Lavaux And Jenssens' LCG
+    """
+
+    def __init__(self):
+        super().__init__(31167285, 1, 281474976710656)
+
+
+class Haynes(LCG):
+    """
+    Haynes' LCG
+    """
+
+    def __init__(self):
+        super().__init__(6364136223846793005, 1, 18446744073709552000)
 
 
+class LaggedFibonnaci(RandomNumberGenerator):
+    """
+    Lagged Fibonnaci generator algorithm
+    """
+
+    def __init__(self, l, k, m):
+        self.l = l
+        self.k = k
+        self.m = m
+        self.ParkMiller = ParkMiller()
+        self.values = []
+
+    def seed(self, seed):
+        self.ParkMiller.seed(seed)
+        self.values = [self.ParkMiller.random() for i in range(max(self.l, self.k))]
+
+    def random(self):
+        # init values if non-existents
+        if not (self.values):
+            self.values = [self.ParkMiller.random() for i in range(max(self.l, self.k))]
+        val = (self.values[-self.l] + self.values[-self.k]) % self.m
+        self.values.append(val)
+        return self.values[-1]
+
+    def randomNorm(self):
+        return random() / (self.m + 1)
+
+
+class MitchelMoore(LaggedFibonnaci):
+    """
+    Mitchel and Moore's Lagged Fibonnaci
+    we use m = 2^32
+    """
+
+    def __init__(self):
+        super().__init__(24, 55, 4294967296)
+
+
+class MersenneTwister(RandomNumberGenerator):
+    """
+    MersenneTwister algorithm (native random.random())
+    """
+
+    def __init__(self):
+        super().__init__()
+
+    def seed(self, seed):
+        random.seed(seed)
+
+    def randomNorm(self):
+        return random.random()
+
+    def random(self):
+        return self.randomNorm()
+
+
+class CNS(RandomNumberGenerator):
+    """
+    Cryptography Network Security
+    """
+
+    def __init__(self, x0, M):
+        super().__init__()
+        self.M = M
+        self.x = x0  # must verify pgcd(M,x0) = 1
+
     def seed(self, seed):
         self.x = seed
+
+    def random(self):
+        self.x = pow(self.x, 2) % self.M
+        return self.x
+
+    def randomNorm(self):
+        return self.random() / (self.M + 1)
+
+
+class BlumBlumShub(CNS):
+    """
+    Blum Blum Shub
+    """
+
+    def __init__(self):
+        super().__init__(7817, 56923661)
+
+    def seed(self, seed):
+        return  # do nothing
diff --git a/Random/graph.py b/Random/graph.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Random/main.py b/Random/main.py
index 3ab482e7064ff823357fbfbfda633d5fd4f8ba31..3fc897886114252e251d8fca901cb800eb85a8e3 100644
--- a/Random/main.py
+++ b/Random/main.py
@@ -1,7 +1,28 @@
-import generators
+from generators import *
+from datetime import datetime
+import matplotlib.pyplot as plt
+import numpy as np
+
 
 if __name__=="__main__":
-    LCG = generators.LCG(5, 1, 1)
-    LCG.seed(0)
-    print(LCG.random())
 
+    generators = [ParkMiller(), KnuthLewis(), Marsaglia()
+                  , LavauxJenssens(), Haynes(), MitchelMoore()
+                  , MersenneTwister(), BlumBlumShub()]
+    
+    seed = datetime.now().timestamp()
+    N = 1000
+    RESOLUTION = 100
+
+    for e in generators:
+        e.seed(seed)
+        res = e.batchRandomNormalized(N)
+        
+        #matplotlib prep
+        #see https://matplotlib.org/stable/gallery/statistics/histogram_features.html#sphx-glr-gallery-statistics-histogram-features-py
+        fig, ax = plt.subplots()
+        n, bins, patches = ax.hist(res, RESOLUTION, density=True)
+        ax.set_xlabel('Value')
+        ax.set_ylabel('Probability density')
+        ax.set_title(type(e).__name__)
+        plt.savefig(type(e).__name__+'.png')