Advertisement
Guest User

PiEnc

a guest
Mar 3rd, 2015
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.72 KB | None | 0 0
  1. import math, sys, base64, pickle, time, sqlite3
  2.  
  3. class Pointer(object):
  4.  
  5.     def __init__(self, coords, direction):
  6.        
  7.         self.coords = coords
  8.  
  9.         self.direction = direction
  10.  
  11. class Sample(object):
  12.  
  13.     def __init__(self, filepath, data_length):
  14.  
  15.  
  16.         self.data_length = data_length
  17.  
  18.  
  19.  
  20.         with open(filepath, 'rb') as datafile:
  21.             self.raw_data = datafile.read()
  22.  
  23.         #Building data_cube
  24.         max_value = int(math.floor(len(self.raw_data) ** (1/3.0)))
  25.         no_planes = 0
  26.         data_cube = []
  27.         pi_position = 0
  28.  
  29.         while no_planes < max_value:
  30.             plane = []
  31.             no_rows = 0
  32.  
  33.             while no_rows < max_value:
  34.                 row = []
  35.                 no_points = 0
  36.  
  37.                 while no_points < max_value:
  38.                     row.append(self.raw_data[pi_position])
  39.                     no_points += 1
  40.                     pi_position += 1
  41.  
  42.                 plane.append(row)
  43.                 no_rows += 1
  44.  
  45.             data_cube.append(plane)
  46.             no_planes += 1
  47.  
  48.         self.data = data_cube
  49.  
  50.     def get_data_from_coordinates(self, coords, direction):
  51.  
  52.         x, y, z = coords
  53.  
  54.         plane = self.data[z]
  55.         row = plane[y]
  56.         point = row[x]
  57.  
  58.         if direction == 'x+':
  59.             modifier = 0
  60.             data = ''
  61.  
  62.             while modifier < self.data_length:
  63.  
  64.                 if x+modifier > len(row) - 1:
  65.                     data = None
  66.                     break
  67.  
  68.                 data += row[x+modifier]
  69.                 modifier += 1
  70.  
  71.  
  72.         elif direction == 'x-':
  73.  
  74.             modifier = 0
  75.             data = ''
  76.  
  77.  
  78.             while modifier < self.data_length:
  79.                 if x - modifier < 0:
  80.                     data = None
  81.                     break
  82.  
  83.                 data += row[x-modifier]
  84.                 modifier += 1
  85.  
  86.  
  87.         elif direction == 'y+':
  88.  
  89.             selected_row = []
  90.  
  91.             for row in plane:
  92.                 selected_row.append(row[x])
  93.  
  94.             modifier = 0
  95.             data = ''
  96.             pos = y
  97.  
  98.             while modifier < self.data_length:
  99.  
  100.                 if pos+modifier > len(selected_row) - 1:
  101.                     data = None
  102.                     break
  103.  
  104.                 data += selected_row[pos + modifier]
  105.  
  106.                 modifier += 1
  107.  
  108.  
  109.  
  110.  
  111.         elif direction == 'y-':
  112.  
  113.             selected_row = []
  114.  
  115.             for row in plane:
  116.                 selected_row.append(row[x])
  117.  
  118.             modifier = 0
  119.             data = ''
  120.             pos = y
  121.  
  122.             while modifier < self.data_length:
  123.  
  124.                 if pos - modifier < 0:
  125.                     data = None
  126.                     break
  127.  
  128.                 data += selected_row[pos - modifier]
  129.  
  130.                 modifier += 1
  131.  
  132.  
  133.  
  134.  
  135.         elif direction == 'z+':
  136.             selected_row = []
  137.  
  138.             for plane in self.data:
  139.                 row = plane[y]
  140.                 selected_row.append(row[x])
  141.  
  142.             modifier = 0
  143.             data = ''
  144.             pos = z
  145.  
  146.             while modifier < self.data_length:
  147.  
  148.                 if pos+modifier > len(selected_row) - 1:
  149.                     data = None
  150.                     break
  151.  
  152.                 data += selected_row[pos+modifier]
  153.  
  154.                 modifier += 1
  155.  
  156.  
  157.         elif direction == 'z-':
  158.             selected_row = []
  159.  
  160.             for plane in self.data:
  161.                 row = plane[y]
  162.                 selected_row.append(row[x])
  163.  
  164.             modifier = 0
  165.             data = ''
  166.             pos = z
  167.             while modifier < self.data_length:
  168.  
  169.                 if pos - modifier < 0:
  170.                     data = None
  171.                     break
  172.  
  173.                 data += selected_row[pos - modifier]
  174.  
  175.                 modifier += 1
  176.  
  177.         return data
  178.  
  179.  
  180.     def get_pointer_from_data(self, data):
  181.        
  182.         z = 0
  183.         for plane in self.data:
  184.             y = 0
  185.             for row in plane:
  186.                 x = 0
  187.                 for point in row:
  188.                     x_pos_data = self.get_data_from_coordinates((x,y,z), 'x+')
  189.                     x_neg_data = self.get_data_from_coordinates((x,y,z), 'x-')
  190.  
  191.                     y_pos_data = self.get_data_from_coordinates((x,y,z), 'y+')
  192.                     y_neg_data = self.get_data_from_coordinates((x,y,z), 'y-')
  193.  
  194.                     z_pos_data = self.get_data_from_coordinates((x,y,z), 'z+')
  195.                     z_neg_data = self.get_data_from_coordinates((x,y,z), 'z-')
  196.                     dataArray = [x_pos_data, x_neg_data, y_pos_data, y_neg_data, z_pos_data, z_neg_data]
  197.  
  198.                     if data in dataArray:
  199.  
  200.                         data_index = dataArray.index(data)
  201.  
  202.                         directionDict = {0:'x+',
  203.                                             1:'x-',
  204.                                             2:'y+',
  205.                                             3:'y-',
  206.                                             4:'z+',
  207.                                             5:'z-'}
  208.  
  209.                         the_pointer = Pointer((x,y,z), directionDict[data_index])
  210.  
  211.                         print("({0}, {1}, {2}) | {3}".format(x,y,z, directionDict[data_index]))
  212.  
  213.                         return the_pointer
  214.  
  215.                     x += 1
  216.                 y += 1
  217.             z += 1
  218.  
  219.         print("NOT FOUND")
  220.  
  221. class Cache(object):
  222.  
  223.     def __init__(self):
  224.  
  225.         self.con = sqlite3.connect('cache.db')
  226.  
  227.         self.cur = self.con.cursor()
  228.  
  229.     def init_cache(self):
  230.         self.cur.execute("CREATE TABLE Cache (data TEXT, x INT, y INT, z INT, direction TEXT) ")
  231.  
  232.  
  233.     def destroy_cache(self):
  234.         self.cur.execute("DROP TABLE IF EXISTS Cache")
  235.  
  236.     def add_to_cache(self, pointer)
  237.  
  238. class data_bundle(object):
  239.  
  240.     def __init__(self, data_sample, raw_data = ""):
  241.  
  242.         self.raw_data = raw_data
  243.         self.chunk_size = 2
  244.         self.sample = data_sample
  245.  
  246.         #table
  247.         self.conversion_table = { 'a':'01',
  248.                             'b':'02',
  249.                             'c':'03',
  250.                             'd':'04',
  251.                             'e':'05',
  252.                             'f':'06',
  253.                             'g':'07',
  254.                             'h':'08',
  255.                             'i':'09',
  256.                             'j':'10',
  257.                             'k':'11',
  258.                             'l':'12',
  259.                             'm':'13',
  260.                             'n':'14',
  261.                             'o':'15',
  262.                             'p':'16',
  263.                             'q':'17',
  264.                             'r':'18',
  265.                             's':'19',
  266.                             't':'20',
  267.                             'u':'21',
  268.                             'v':'22',
  269.                             'w':'23',
  270.                             'x':'24',
  271.                             'y':'25',
  272.                             'z':'26',
  273.                             'A':'27',
  274.                             'B':'28',
  275.                             'C':'29',
  276.                             'D':'30',
  277.                             'E':'31',
  278.                             'F':'32',
  279.                             'G':'33',
  280.                             'H':'34',
  281.                             'I':'35',
  282.                             'J':'36',
  283.                             'K':'37',
  284.                             'L':'38',
  285.                             'M':'39',
  286.                             'N':'40',
  287.                             'O':'41',
  288.                             'P':'42',
  289.                             'Q':'43',
  290.                             'R':'44',
  291.                             'S':'45',
  292.                             'T':'46',
  293.                             'U':'47',
  294.                             'V':'48',
  295.                             'W':'49',
  296.                             'X':'50',
  297.                             'Y':'51',
  298.                             'Z':'52',
  299.                             '0':'53',
  300.                             '1':'54',
  301.                             '2':'55',
  302.                             '3':'56',
  303.                             '4':'57',
  304.                             '5':'58',
  305.                             '6':'59',
  306.                             '7':'60',
  307.                             '8':'61',
  308.                             '9':'62',
  309.                             '+':'63',
  310.                             '/':'64' }
  311.  
  312.         #Future Attributes
  313.         self.chunked_data = []
  314.         self.pointers = []
  315.  
  316.         #Chunking
  317.         self.chunk_data()
  318.  
  319.         #Getting Pointers
  320.         self.get_pointers()
  321.  
  322.     def chunk_data(self):
  323.  
  324.         raw_chunks = [self.raw_data[i:i+self.chunk_size] for i in range(0, len(self.raw_data), self.chunk_size)]
  325.         clean_chunks = []
  326.         for chunk in raw_chunks:
  327.             chunk_list = list(chunk)
  328.  
  329.             while len(chunk_list) < self.chunk_size:
  330.                 chunk_list.reverse()
  331.                 chunk_list.append('^')
  332.                 chunk_list.reverse()
  333.  
  334.             chunk = ''.join(chunk_list)
  335.             clean_chunks.append(chunk)
  336.  
  337.  
  338.         for chunk in clean_chunks:
  339.  
  340.             code = ""
  341.  
  342.             for char in chunk:
  343.  
  344.                 if char in self.conversion_table.keys():
  345.                     char_symbol = self.conversion_table[char]
  346.                 else:
  347.                     char_symbol = '00'
  348.  
  349.                 code += char_symbol
  350.  
  351.             self.chunked_data.append(code)
  352.  
  353.     def get_pointers(self):
  354.  
  355.         mycache = Cache()
  356.         mycache.init_cache()
  357.  
  358.         max_length = len(self.chunked_data)
  359.         counter = 0
  360.  
  361.         for chunk in self.chunked_data:
  362.  
  363.             new_pointer = self.sample.get_pointer_from_data(chunk)
  364.             self.pointers.append(new_pointer)
  365.             counter+=1
  366.             print("{0}/{1}".format(counter, max_length))
  367.  
  368.         mycache.destroy_cache()
  369.  
  370.     def dump(self, filename):
  371.  
  372.         with open(filename, 'wb') as opened_file:
  373.  
  374.             pointer_array = []
  375.  
  376.             for pointer in self.pointers:
  377.                 x = pointer.coords[0]
  378.                 y = pointer.coords[1]
  379.                 z = pointer.coords[2]  
  380.                 direction = pointer.direction
  381.  
  382.                 data = [x,y,z,direction]
  383.  
  384.                 pointer_array.append(data)
  385.  
  386.             opened_file.write(pickle.dumps(pointer_array))
  387.  
  388.     def reload(self, filename):
  389.  
  390.         #Resetting Attributes
  391.         self.pointers = []
  392.         self.chunked_data = []
  393.         self.raw_data = ""
  394.  
  395.         pointers_array = pickle.loads(filename)
  396.  
  397.  
  398.         #Rebuilding pointers...
  399.         for pointer_data in pointers_array:
  400.  
  401.             pointer = Pointer((pointer_data[0], pointer_data[1], pointer_data[2]), pointer_data[3])
  402.  
  403.             self.pointers.append(pointer)
  404.  
  405.         #Recovering data from pi...
  406.         for pointer in self.pointers:
  407.             coords = pointer.coords
  408.             direction = pointer.direction
  409.  
  410.             data = self.sample.get_data_from_coordinates(coords, direction)
  411.  
  412.             self.chunked_data.append(data)
  413.  
  414.         #De-Chunking Data
  415.  
  416.         print self.chunked_data
  417.  
  418.         for chunk in self.chunked_data:
  419.  
  420.             one_found = False
  421.             two_found = False
  422.  
  423.             char_one = chunk[0] + chunk[1]
  424.             char_two = chunk[2] + chunk[3]
  425.  
  426.  
  427.             for key in self.conversion_table.keys():
  428.  
  429.                 if char_one == self.conversion_table[key] and not one_found:
  430.                     char_one = key
  431.                     one_found = True
  432.  
  433.                 if char_two == self.conversion_table[key] and not two_found:
  434.                     char_two = key
  435.                     two_found = True
  436.  
  437.             if not one_found:
  438.                 char_one = ''
  439.  
  440.             if not two_found:
  441.                 char_two = ''
  442.  
  443.             self.raw_data += char_one + char_two
  444.  
  445.  
  446.  
  447.  
  448. def init():
  449.  
  450.     #Removing useless argument
  451.     arguments = sys.argv
  452.     arguments.reverse()
  453.     arguments.pop()
  454.     arguments.reverse()
  455.  
  456.     if len(arguments) < 2 or len(arguments) > 3:
  457.         sys.exit("USAGE: pienc [action] [filename] {output}")
  458.  
  459.  
  460.     #Getting file names
  461.     action = arguments[0]
  462.     filename = arguments[1]
  463.  
  464.     if len(arguments) == 3:
  465.         outfile = arguments[3]
  466.  
  467.     else:
  468.         outfile = filename+".out"
  469.  
  470.  
  471.     input_file = ""
  472.  
  473.  
  474.     #Reading file
  475.     try:
  476.         with open(filename, 'rb') as infile:
  477.             input_file = infile.read()
  478.     except:
  479.         sys.exit("An error occured while reading the file")
  480.  
  481.  
  482.     #Action
  483.     if action == 'e':
  484.         encode(input_file, outfile)
  485.  
  486.     elif action == 'd':
  487.         decode(input_file, outfile)
  488.  
  489.     else:
  490.         sys.exit("Invalid command: '{0}'".format(action))
  491.  
  492. def encode(infile, outfile):
  493.  
  494.     data = base64.b64encode(infile)
  495.     data = data.replace("=", "") #Cleaning up data
  496.     data_sample = Sample('pi.dat', 4)
  497.  
  498.     bundled_data = data_bundle(data_sample, data)
  499.  
  500.     bundled_data.dump(outfile)
  501.  
  502. def decode(infile, outfile):
  503.  
  504.     data_sample = Sample('pi.dat', 4)
  505.     bundled_data = data_bundle(data_sample)
  506.  
  507.     bundled_data.reload(infile)
  508.  
  509.     data = bundled_data.raw_data
  510.  
  511.     missing_padding = 4 - len(data) % 4
  512.     if missing_padding:
  513.         data += b'='* missing_padding
  514.  
  515.     clean_data = base64.decodestring(data)
  516.  
  517.     print(outfile)
  518.  
  519.     with open(outfile, 'a+') as file_out:
  520.  
  521.         file_out.write(clean_data)
  522.  
  523. start_time = time.time()
  524. init()
  525. print("--- %s seconds ---" % (time.time() - start_time))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement