def scale_image(file, size =64): """
Read an image file, change it to grayscale (0-255),
and scale it so that its dimension is at most size x size,
keeping the image's aspect ratio.
"""
im = PIL.Image.open(file)
im = im.convert('L')#change image to grayscale (0 to 255)
def image_to_binary(image): """
Convert a grayscale (0-255) image to its binary string representation.
Change the last pixel to 1 to make it a prime number more easily.
"""
width, height = image.size
pixels = np.asarray(image)#store pixel value in numpy array
binary_pixels =(pixels >128).astype(np.int)#low values go to 0, high values go to 1
binary_pixels[(-1,-1)]=1#make sure last pixel is 1 to make it a prime more easily
binary_string ="".join(binary_pixels.flatten().astype(np.str).tolist())
return width, height, binary_string #return width and height along with 1-dimension binary representation
def is_binary_string_prime(x, n_tests =50): """
Check if the binary string x is prime using gmpy2's Miller-Rabin
algorithm with n_tests steps.
"""
num =int(x,2)#convert binary string to decimal number return gmpy2.is_prime(num, n_tests)
def mutate_to_prime(x, max_tries =12000): """
Given a binary string x, flip just one bit to make it a prime number.
max_tries is the maximum number of tries before giving up.
If x is N bits long, probability that x is a prime is about 1/(N log(2)),
so max_tries about a few times N log(2) should be OK.
The first prime found will be returned.
If no prime is found, None will be returned.
"""
if is_binary_string_prime(x): return x #if x is already prime, just return it.
found_prime =False for k inrange(max_tries):
m = mutate(x)#try flipping one bit if is_binary_string_prime(m): #if it's a prime, return it return m
import PIL.Image import gmpy2 importrandom import numpy as np importmath
def scale_image(file, size =64): """
Read an image file, change it to grayscale (0-255),
and scale it so that its dimension is at most size x size,
keeping the image's aspect ratio.
"""
im = PIL.Image.open(file)
im = im.convert('L')#change image to grayscale (0 to 255)
def image_to_binary(image): """
Convert a grayscale (0-255) image to its binary string representation.
Change the last pixel to 1 to make it a prime number more easily.
"""
width, height = image.size
pixels = np.asarray(image)#store pixel value in numpy array
binary_pixels =(pixels >128).astype(np.int)#low values go to 0, high values go to 1
binary_pixels[(-1,-1)]=1#make sure last pixel is 1 to make it a prime more easily
binary_string ="".join(binary_pixels.flatten().astype(np.str).tolist())
return width, height, binary_string #return width and height along with 1-dimension binary representation
def mutate(x): """
Given a binary string x, flip one random bit and return the result.
"""
i =random.randint(0,len(x)-1)#location to flip a bit
if x[i]=='0':
flip ='1' else:
flip ='0'
result = x[:i] + flip + x[i+1:]#copy x to result, except one flipped bit
return result
def is_binary_string_prime(x, n_tests =50): """
Check if the binary string x is prime using gmpy2's Miller-Rabin
algorithm with n_tests steps.
"""
num =int(x,2)#convert binary string to decimal number return gmpy2.is_prime(num, n_tests)
def mutate_to_prime(x, max_tries =12000): """
Given a binary string x, flip just one bit to make it a prime number.
max_tries is the maximum number of tries before giving up.
If x is N bits long, probability that x is a prime is about 1/(N log(2)),
so max_tries about a few times N log(2) should be OK.
The first prime found will be returned.
If no prime is found, None will be returned.
"""
if is_binary_string_prime(x): return x #if x is already prime, just return it.
found_prime =False for k inrange(max_tries):
m = mutate(x)#try flipping one bit if is_binary_string_prime(m): #if it's a prime, return it return m
returnNone
def print_pic(x, width): """
Given a binary string x, print it
so that each line contains width characters.
"""
height =int(len(x)/width) for row inrange(height): print(x[row*width : row*width+width])
def pic_to_prime(file, size =64, max_tries =12000): """
Open an image file and attempt to
print it as a binary string picture
that is a prime number.
"""
im = scale_image(file, size)
width, height, binary = image_to_binary(im)
x = mutate_to_prime(binary, max_tries) if x:
print_pic(x,width)
num =int(x,2) print("\nThe number is {} in base 10.".format(num)) print("It has {} digits".format(len(str(num)))) print("It's likely a prime with probability = {}".format(1-math.pow(0.5,50)))
def main(): importsys
usage ="""
python pic_to_prime.py image_file [size] [max_tries]
Will attempt to convert image_file into a black and white picture whose ASCII representation is
(black = 0, white = 1) and the string of 0's and 1's forms a binary number which is likely prime with
an extremely high probablity.
size is an optional parameter. The converted image's dimension will be at most size x size
Default value for size is 64
max_tries is an optional parameter. It's the maximum number of tries to flip one bit in the converted image
until it's a prime number. If max_tries is reached without find a prime, the program does not return any Ascii image.
Typically, setting max_tries to be a few times size x size should be sufficient.
Default value for max_tries is 12,000
"""