I have a .raw image file, and I'd like to use python3 to read all the data from the file and print a hex dump of this image.
If possible, i'd like it to run in the terminal window.
This is the code I have found and adapted so far:
import sys
src = sys.argv[1]
def hexdump( src, length=16, sep='.' ):
result = [];
# Python3 support
try:
xrange(0,1);
except NameError:
xrange = range;
for i in xrange(0, len(src), length):
subSrc = src[i:i+length];
hexa = '';
isMiddle = False;
for h in xrange(0,len(subSrc)):
if h == length/2:
hexa += ' ';
h = subSrc[h];
if not isinstance(h, int):
h = ord(h);
h = hex(h).replace('0x','');
if len(h) == 1:
h = '0'+h;
hexa += h+' ';
hexa = hexa.strip(' ');
text = '';
for c in subSrc:
if not isinstance(c, int):
c = ord(c);
if 0x20 <= c < 0x7F:
text += chr(c);
else:
text += sep;
result.append(('%08X: %-'+str(length*(2+1)+1)+'s |%s|') % (i, hexa, text));
return '\n'.join(result);
if __name__ == "__main__":
print(hexdump(src, length=16, sep='.'))
I've been using the command in the terminal:
python3 nameoffile.py nameofrawfile.raw
and it just gives me the hex values of the name of the raw file. I'd like it to read the raw file then give be all the data from it in hex.
Thanks.
EDIT: I'd like to use python as once the file is represented in hex values, I'd like to do further processing on it using python.
One-liner:
$ python -c \
"import codecs; print(codecs.encode(open('file.raw', 'rb').read(), 'hex').decode())"
The problem is you pass the name of the file to hexdump() which treats it like data. The following corrects that and applies other relatively minor fixes to your code (and seems to work in my limited testing):
try:
xrange
except NameError: # Python3
xrange = range
def hexdump(filename, length=16, sep='.'):
result = []
with open(filename, 'rb') as file:
src = file.read() # Read whole file into memory
for i in xrange(0, len(src), length):
subSrc = src[i:i+length]
hexa = ''
isMiddle = False;
for h in xrange(0,len(subSrc)):
if h == length/2:
hexa += ' '
h = subSrc[h]
if not isinstance(h, int):
h = ord(h)
h = hex(h).replace('0x','')
if len(h) == 1:
h = '0'+h;
hexa += h+' '
hexa = hexa.strip(' ')
text = ''
for c in subSrc:
if not isinstance(c, int):
c = ord(c)
if 0x20 <= c < 0x7F:
text += chr(c)
else:
text += sep;
result.append(('%08X: %-'+str(length*(2+1)+1)+'s |%s|') %
(i, hexa, text))
return '\n'.join(result)
if __name__ == "__main__":
import sys
filename = sys.argv[1]
print(hexdump(filename, length=16, sep='.'))
Related
I found a Python script that I'm trying to convert to Lua. I believe I have it just about converted, but the code isn't quite working properly, so I need assistance as I do not know Python at all, and can only guess at the intentions. This is merely a color converter to convert RGB color to xterm 256. The table is quite huge, so I've truncated it for ease of reading.
Python code:
import sys, re
CLUT = [ # color look-up table
# 8-bit, RGB hex
# Primary 3-bit (8 colors). Unique representation!
('00', '000000'),
('01', '800000'),
('02', '008000'),
('03', '808000'),
('04', '000080'),
('05', '800080'),
('06', '008080'),
('07', 'c0c0c0'),
]
def _str2hex(hexstr):
return int(hexstr, 16)
def _strip_hash(rgb):
# Strip leading `#` if exists.
if rgb.startswith('#'):
rgb = rgb.lstrip('#')
return rgb
def _create_dicts():
short2rgb_dict = dict(CLUT)
rgb2short_dict = {}
for k, v in short2rgb_dict.items():
rgb2short_dict[v] = k
return rgb2short_dict, short2rgb_dict
def short2rgb(short):
return SHORT2RGB_DICT[short]
def print_all():
""" Print all 256 xterm color codes.
"""
for short, rgb in CLUT:
sys.stdout.write('\033[48;5;%sm%s:%s' % (short, short, rgb))
sys.stdout.write("\033[0m ")
sys.stdout.write('\033[38;5;%sm%s:%s' % (short, short, rgb))
sys.stdout.write("\033[0m\n")
print "Printed all codes."
print "You can translate a hex or 0-255 code by providing an argument."
def rgb2short(rgb):
""" Find the closest xterm-256 approximation to the given RGB value.
#param rgb: Hex code representing an RGB value, eg, 'abcdef'
#returns: String between 0 and 255, compatible with xterm.
>>> rgb2short('123456')
('23', '005f5f')
>>> rgb2short('ffffff')
('231', 'ffffff')
>>> rgb2short('0DADD6') # vimeo logo
('38', '00afd7')
"""
rgb = _strip_hash(rgb)
incs = (0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff)
# Break 6-char RGB code into 3 integer vals.
parts = [ int(h, 16) for h in re.split(r'(..)(..)(..)', rgb)[1:4] ]
res = []
for part in parts:
i = 0
while i < len(incs)-1:
s, b = incs[i], incs[i+1] # smaller, bigger
if s <= part <= b:
s1 = abs(s - part)
b1 = abs(b - part)
if s1 < b1: closest = s
else: closest = b
res.append(closest)
break
i += 1
#print '***', res
res = ''.join([ ('%02.x' % i) for i in res ])
equiv = RGB2SHORT_DICT[ res ]
#print '***', res, equiv
return equiv, res
RGB2SHORT_DICT, SHORT2RGB_DICT = _create_dicts()
#---------------------------------------------------------------------
if __name__ == '__main__':
import doctest
doctest.testmod()
if len(sys.argv) == 1:
print_all()
raise SystemExit
arg = sys.argv[1]
if len(arg) < 4 and int(arg) < 256:
rgb = short2rgb(arg)
sys.stdout.write('xterm color \033[38;5;%sm%s\033[0m -> RGB exact \033[38;5;%sm%s\033[0m' % (arg, arg, arg, rgb))
sys.stdout.write("\033[0m\n")
else:
short, rgb = rgb2short(arg)
sys.stdout.write('RGB %s -> xterm color approx \033[38;5;%sm%s (%s)' % (arg, short, short, rgb))
sys.stdout.write("\033[0m\n")
And my nearly complete translated Lua code:
CLUT = {
-- Primary 3-bit (8 colors). Unique representation!
['00'] = '000000',
['01'] = '800000',
['02'] = '008000',
['03'] = '808000',
['04'] = '000080',
['05'] = '800080',
['06'] = '008080',
['07'] = 'c0c0c0',
}
function _str2hex(hexstr)
return tonumber(hexstr, 16)
end
function _strip_hash(rgb)
-- Strip leading # if exists
return rgb:gsub("^#", "")
end
function _create_dicts()
short2rgb_dict = CLUT
rgb2short_dict = {}
for k,v in pairs(short2rgb_dict) do
rgb2short_dict[v] = k
end
return rgb2short_dict, short2rgb_dict
end
function short2rgb(short)
return short2rgb_dict[short]
end
function rgb2short(rgb)
-- Find closest xterm-256 approximation to the given RGB value
_create_dicts()
rgb = _strip_hash(rgb)
local res = ""
local equiv = ""
local incs = {"0x00", "0x5f", "0x87", "0xaf", "0xd7", "0xff"}
for part in string.gmatch(rgb, "(..)") do
part = tonumber(part, 16)
i = 1
while i < #incs - 1 do
s, b = tonumber(incs[i]), tonumber(incs[i+1])
if s <= part and part <= b then
s1 = math.abs(s - part)
b1 = math.abs(b - part)
end
if s1 < b1 then
closest = s
else
closest = b
res = res .. closest
break
end
i = i + 1
end
end
equiv = rgb2short_dict[res]
return equiv, res
end
I realize that I'm missing the printing portion of the code, but I wasn't sure if that was at all relevant, and I know some of the code I've translated is not correct at all, as the script would be working otherwise. The failures I get are with the rgb2short function with it not returning the proper equiv and res values. How far off am I with my revision? What changes do I need to make to make it absolutely work?
I wound up figuring it out on my own after some hardcore trial and error. The function rgb2short should have been:
function rgb2short(rgb)
-- Find closest xterm-256 approximation to the given RGB value
_create_dicts()
rgb = _strip_hash(rgb)
local res = ""
local equiv = ""
local incs = {"0x00", "0x5f", "0x87", "0xaf", "0xd7", "0xff"}
for part in string.gmatch(rgb, "(..)") do
part = tonumber(part, 16)
i = 1
while i < #incs-1 do
s, b = tonumber(incs[i]), tonumber(incs[i+1])
if s <= part and part <= b then
s1 = math.abs(s - part)
b1 = math.abs(b - part)
--break
--end
if s1 < b1 then
closest = s
else
closest = b
end
res = res .. string.format("%02x", closest)
break
end
i = i + 1
end
end
equiv = rgb2short_dict[res]
return equiv, res
end
I'm following on this tutorial and in part 2 (picture below) it shows that the SHA256 yields a result different than what I get when I ran my python code:
the string is: 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
While the tutorial SHA256 comes to: 600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408
My short python shows:
sha_result = sha256(bitconin_addresss).hexdigest().upper()
print sha_result
32511E82D56DCEA68EB774094E25BAB0F8BDD9BC1ECA1CEEDA38C7A43ACEDDCE
in fact, any online sha256 shows the same python result; so am I missing here something?
You're hashing the string when you're supposed to be hashing the bytes represented by that string.
>>> hashlib.sha256('0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'.decode('hex')).hexdigest().upper()
'600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408'
You could use Gavin's "base58.py", which I believe he no longer shares it on his github page. However you probably could easily google and find different versions of it from github.
Here is one version edited a little by me:
#!/usr/bin/env python
"""encode/decode base58 in the same way that Bitcoin does"""
import math
import sys
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
__b58base = len(__b58chars)
def b58encode(v):
""" encode v, which is a string of bytes, to base58.
"""
long_value = 0L
for (i, c) in enumerate(v[::-1]):
long_value += ord(c) << (8*i) # 2x speedup vs. exponentiation
result = ''
while long_value >= __b58base:
div, mod = divmod(long_value, __b58base)
result = __b58chars[mod] + result
long_value = div
result = __b58chars[long_value] + result
# Bitcoin does a little leading-zero-compression:
# leading 0-bytes in the input become leading-1s
nPad = 0
for c in v:
if c == '\0': nPad += 1
else: break
return (__b58chars[0]*nPad) + result
def b58decode(v):
""" decode v into a string of len bytes
"""
long_value = 0L
for (i, c) in enumerate(v[::-1]):
long_value += __b58chars.find(c) * (__b58base**i)
result = ''
while long_value >= 256:
div, mod = divmod(long_value, 256)
result = chr(mod) + result
long_value = div
result = chr(long_value) + result
nPad = 0
for c in v:
if c == __b58chars[0]: nPad += 1
else: break
result = chr(0)*nPad + result
return result
try:
import hashlib
hashlib.new('ripemd160')
have_crypto = True
except ImportError:
have_crypto = False
def hash_160(public_key):
if not have_crypto:
return ''
h1 = hashlib.sha256(public_key).digest()
r160 = hashlib.new('ripemd160')
r160.update(h1)
h2 = r160.digest()
return h2
def hash_160_to_bc_address(h160, version="\x00"):
if not have_crypto:
return ''
vh160 = version+h160
h3=hashlib.sha256(hashlib.sha256(vh160).digest()).digest()
addr=vh160+h3[0:4]
return b58encode(addr)
def public_key_to_bc_address(public_key, version="\x00"):
if not have_crypto or public_key is None:
return ''
h160 = hash_160(public_key)
return hash_160_to_bc_address(h160, version=version)
def sec_to_bc_key(sec, version="\x80"):
if not have_crypto or sec is None:
return ''
vsec = version+sec +"\x01"
hvsec=hashlib.sha256(hashlib.sha256(vsec).digest()).digest()
return b58encode(vsec+hvsec[0:4])
def bc_key_to_sec(prv):
return b58decode(prv)[1:33]
def bc_address_to_hash_160(addr):
bytes = b58decode(addr)
return bytes[1:21]
if __name__ == '__main__':
if len(sys.argv) > 1:
if sys.argv[1] == '-en':
print b58encode(sys.argv[2].decode('hex_codec'))
if sys.argv[1] == '-de':
print b58decode(sys.argv[2]).encode('hex_codec')
if sys.argv[1] == '-pub':
print public_key_to_bc_address(sys.argv[2].decode('hex_codec'))
if sys.argv[1] == '-adr':
print bc_address_to_hash_160(sys.argv[2]).encode('hex_codec')
if sys.argv[1] == '-sec':
print sec_to_bc_key(sys.argv[2].decode('hex_codec'))
if sys.argv[1] == '-prv':
print bc_key_to_sec(sys.argv[2]).encode('hex_codec')
else:
print ''
print 'Usage: ./base58.py [options]'
print ''
print ' -en converts hex to base58'
print ' -de converts base58 to hex'
print
print ' -pub public_key_to_bc_address'
print ' -adr bc_address_to_hash_160'
print
print ' -sec sec_to_bc_key'
print ' -prv bc_key_to_sec'
print
To answer your specific question, based on above code you could use this command:
hashlib.sha256('0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'.decode('hex_codec')).digest().encode('hex_codec').upper()
My dreambox compatible video recorder stores event information table ".eit" files with every recording. I'd like to work with this information to rearrange my recordings.
A similar question came up in http://www.i-have-a-dreambox.com/wbb2/thread.php?threadid=186234&sid=3b36acb1ba62e4724cb47216ce08a564
The format seems to be a binary format as outlined in:
https://de.wikipedia.org/wiki/Event_Information_Table
and
http://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.14.01_60/en_300468v011401p.pdf
I am now looking for a parser for such files. Where could I find one that works with files and does not assume a broadcast stream as input?
What did i try so far?
I searched the web and found the following links and pointers:
There seems to be a java library
https://docs.oracle.com/javame/config/cdc/opt-pkgs/api/jsr927/javax/tv/service/guide/ProgramEvent.html
which is part of the JSR 927 https://jcp.org/en/jsr/detail?id=927
specification.
As it looks this libary is only available for Java-ME see https://en.wikipedia.org/wiki/Java_TV
If found some dvb related EIT code snippets e.g.
https://github.com/jinfeng-geeya/3202C/blob/master/SRC/lib/libdvb/libepg/eit_parser.c
or
http://linuxtv.org/docs/libdvbv5/eit_8h.html
as part of the Kamaelia DVB Tools Project http://www.kamaelia.org/Developers/Projects/DVBTools.html there seems to be a python solution:
http://pydoc.net/Python/Kamaelia/0.6.0/Kamaelia.Device.DVB.Parse.ParseEventInformationTable/
The closest I found so far was from a hint athttp://forums.openpli.org/topic/29141-eit-file-format/ which points to:
https://github.com/betonme/e2openplugin-EnhancedMovieCenter/blob/master/src/EitSupport.py
Currently I am pursuing to go from this Open Source Python Code.
This is a Python script that seems to be a valid start.
It's available as opensource at https://github.com/WolfgangFahl/eitparser where you'll find the latest python3 compatible version and documentation.
When you call it with
python EitParser.py SomeEitFile
it will print out the name and description of the eit file.
Add you language codes as you need e.g. from https://github.com/libo/Enigma2/blob/master/lib/python/Tools/ISO639.py
#!/usr/bin/python
# encoding: utf-8
#
# EitSupport
# Copyright (C) 2011 betonme
# Copyright (C) 2016 Wolfgang Fahl
#
# This EITParser is based on:
# https://github.com/betonme/e2openplugin-EnhancedMovieCenter/blob/master/src/EitSupport.py
#
# In case of reuse of this source code please do not remove this copyright.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For more information on the GNU General Public License see:
# <http://www.gnu.org/licenses/>.
#
import os
import struct
import time
from datetime import datetime
#from Components.config import config
#from Components.Language import language
#from EMCTasker import emcDebugOut
#from IsoFileSupport import IsoSupport
#from MetaSupport import getInfoFile
#def crc32(data):
# poly = 0x4c11db7
# crc = 0xffffffffL
# for byte in data:
# byte = ord(byte)
# for bit in range(7,-1,-1): # MSB to LSB
# z32 = crc>>31 # top bit
# crc = crc << 1
# if ((byte>>bit)&1) ^ z32:
# crc = crc ^ poly
# crc = crc & 0xffffffffL
# return crc
decoding_charSpecHR = {u'Ć': u'\u0106', u'æ': u'\u0107', u'®': u'\u017D', u'¾': u'\u017E', u'©': u'\u0160', u'¹': u'\u0161', u'Č': u'\u010C', u'è': u'\u010D', u'ð': u'\u0111'}
decoding_charSpecCZSK = {u'Ï'+u'C': u'Č',u'Ï'+u'E': u'Ě',u'Ï'+u'L': u'Ľ',u'Ï'+u'N': u'Ň',u'Ï'+u'R': u'Ř',u'Ï'+u'S': u'Š',u'Ï'+u'T': u'Ť',u'Ï'+u'Z': u'Ž',u'Ï'+u'c': u'č',u'Ï'+u'd': u'ď',u'Ï'+u'e': u'ě',u'Ï'+u'l': u'ľ', u'Ï'+u'n': u'ň',
u'Ï'+u'r': u'ř',u'Ï'+u's': u'š',u'Ï'+u't': u'ť',u'Ï'+u'z': u'ž',u'Ï'+u'D': u'Ď',u'Â'+u'A': u'Á',u'Â'+u'E': u'É',u'Â'+u'I': u'Í',u'Â'+u'O': u'Ó',u'Â'+u'U': u'Ú',u'Â'+u'a': u'á',u'Â'+u'e': u'é',u'Â'+u'i': u'í',u'Â'+u'o': u'ó',
u'Â'+u'u': u'ú',u'Â'+u'y': u'ý',u'Ã'+u'o': u'ô',u'Ã'+u'O': u'Ô',u'Ê'+u'u': u'ů',u'Ê'+u'U': u'Ů',u'È'+u'A': u'Ä',u'È'+u'E': u'Ë',u'È'+u'I': u'Ï',u'È'+u'O': u'Ö',u'È'+u'U': u'Ü',u'È'+u'Y': u'Ÿ',u'È'+u'a': u'ä',u'È'+u'e': u'ë',
u'È'+u'i': u'ï',u'È'+u'o': u'ö',u'È'+u'u': u'ü',u'È'+u'y': u'ÿ'}
def convertCharSpecHR(text):
for i, j in decoding_charSpecHR.iteritems():
text = text.replace(i, j)
return text
def convertCharSpecCZSK(text):
for i, j in decoding_charSpecCZSK.iteritems():
text = text.replace(i, j)
return text
def parseMJD(MJD):
# Parse 16 bit unsigned int containing Modified Julian Date,
# as per DVB-SI spec
# returning year,month,day
YY = int( (MJD - 15078.2) / 365.25 )
MM = int( (MJD - 14956.1 - int(YY*365.25) ) / 30.6001 )
D = MJD - 14956 - int(YY*365.25) - int(MM * 30.6001)
K=0
if MM == 14 or MM == 15: K=1
return (1900 + YY+K), (MM-1-K*12), D
def unBCD(byte):
return (byte>>4)*10 + (byte & 0xf)
#from Tools.ISO639 import LanguageCodes
# -*- coding: iso-8859-2 -*-
LanguageCodes = { }
LanguageCodes["deu"] = LanguageCodes["ger"] = LanguageCodes["de"] = ("German", "Germanic")
LanguageCodes["fra"] = LanguageCodes["fre"] = LanguageCodes["fr"] = ("French", "Romance")
def language_iso639_2to3(alpha2):
ret = alpha2
if alpha2 in LanguageCodes:
language = LanguageCodes[alpha2]
for alpha, name in LanguageCodes.items():
if name == language:
if len(alpha) == 3:
return alpha
return ret
#TEST
#print LanguageCodes["sv"]
#print language_iso639_2to3("sv")
# Eit File support class
# Description
# http://de.wikipedia.org/wiki/Event_Information_Table
class EitList():
EIT_SHORT_EVENT_DESCRIPTOR = 0x4d
EIT_EXTENDED_EVENT_DESCRIPOR = 0x4e
def __init__(self, path=None):
self.eit_file = None
#TODO
# The dictionary implementation could be very slow
self.eit = {}
self.iso = None
self.__newPath(path)
self.__readEitFile()
def __newPath(self, path):
name = None
if path:
if self.eit_file != path:
self.eit_file = path
def __mk_int(self, s):
return int(s) if s else 0
def __toDate(self, d, t):
if d and t:
#TODO Is there another fast and safe way to get the datetime
try:
return datetime(int(d[0]), int(d[1]), int(d[2]), int(t[0]), int(t[1]))
except ValueError:
return None
else:
return None
##############################################################################
## Get Functions
def getEitsid(self):
return self.eit.get('service', "") #TODO
def getEitTsId(self):
return self.eit.get('transportstream', "") #TODO
def getEitWhen(self):
return self.eit.get('when', "")
def getEitStartDate(self):
return self.eit.get('startdate', "")
def getEitStartTime(self):
return self.eit.get('starttime', "")
def getEitDuration(self):
return self.eit.get('duration', "")
def getEitName(self):
return self.eit.get('name', "").strip()
def getEitDescription(self):
return self.eit.get('description', "").strip()
# Wrapper
def getEitShortDescription(self):
return self.getEitName()
def getEitExtendedDescription(self):
return self.getEitDescription()
def getEitLengthInSeconds(self):
length = self.eit.get('duration', "")
#TODO Is there another fast and safe way to get the length
if len(length)>2:
return self.__mk_int((length[0]*60 + length[1])*60 + length[2])
elif len(length)>1:
return self.__mk_int(length[0]*60 + length[1])
else:
return self.__mk_int(length)
def getEitDate(self):
return self.__toDate(self.getEitStartDate(), self.getEitStartTime())
##############################################################################
## File IO Functions
def __readEitFile(self):
data = ""
path = self.eit_file
#lang = language.getLanguage()[:2]
lang = language_iso639_2to3( "de" )
#print lang + str(path)
if path and os.path.exists(path):
#print "Reading Event Information Table " + str(path)
# Read data from file
# OE1.6 with Pyton 2.6
#with open(self.eit_file, 'r') as file: lines = file.readlines()
f = None
try:
f = open(path, 'rb')
#lines = f.readlines()
data = f.read()
except Exception, e:
emcDebugOut("[META] Exception in readEitFile: " + str(e))
finally:
if f is not None:
f.close()
# Parse the data
if data and 12 <= len(data):
# go through events
pos = 0
e = struct.unpack(">HHBBBBBBH", data[pos:pos+12])
event_id = e[0]
date = parseMJD(e[1]) # Y, M, D
time = unBCD(e[2]), unBCD(e[3]), unBCD(e[4]) # HH, MM, SS
duration = unBCD(e[5]), unBCD(e[6]), unBCD(e[7]) # HH, MM, SS
running_status = (e[8] & 0xe000) >> 13
free_CA_mode = e[8] & 0x1000
descriptors_len = e[8] & 0x0fff
if running_status in [1,2]:
self.eit['when'] = "NEXT"
elif running_status in [3,4]:
self.eit['when'] = "NOW"
self.eit['startdate'] = date
self.eit['starttime'] = time
self.eit['duration'] = duration
pos = pos + 12
short_event_descriptor = []
short_event_descriptor_multi = []
extended_event_descriptor = []
extended_event_descriptor_multi = []
component_descriptor = []
content_descriptor = []
linkage_descriptor = []
parental_rating_descriptor = []
endpos = len(data) - 1
while pos < endpos:
rec = ord(data[pos])
length = ord(data[pos+1]) + 2
if rec == 0x4D:
descriptor_tag = ord(data[pos+1])
descriptor_length = ord(data[pos+2])
ISO_639_language_code = str(data[pos+3:pos+5])
event_name_length = ord(data[pos+5])
short_event_description = data[pos+6:pos+6+event_name_length]
if ISO_639_language_code == lang:
short_event_descriptor.append(short_event_description)
short_event_descriptor_multi.append(short_event_description)
elif rec == 0x4E:
ISO_639_language_code = str(data[pos+3:pos+5])
extended_event_description = ""
extended_event_description_multi = ""
for i in range (pos+8,pos+length):
if str(ord(data[i]))=="138":
extended_event_description += '\n'
extended_event_description_multi += '\n'
else:
if data[i]== '\x10' or data[i]== '\x00' or data[i]== '\x02':
pass
else:
extended_event_description += data[i]
extended_event_description_multi += data[i]
if ISO_639_language_code == lang:
extended_event_descriptor.append(extended_event_description)
extended_event_descriptor_multi.append(extended_event_description)
elif rec == 0x50:
component_descriptor.append(data[pos+8:pos+length])
elif rec == 0x54:
content_descriptor.append(data[pos+8:pos+length])
elif rec == 0x4A:
linkage_descriptor.append(data[pos+8:pos+length])
elif rec == 0x55:
parental_rating_descriptor.append(data[pos+2:pos+length])
else:
#print "unsopported descriptor: %x %x" %(rec, pos + 12)
#print data[pos:pos+length]
pass
pos += length
# Very bad but there can be both encodings
# User files can be in cp1252
# Is there no other way?
if short_event_descriptor:
short_event_descriptor = "".join(short_event_descriptor)
else:
short_event_descriptor = "".join(short_event_descriptor_multi)
if short_event_descriptor:
#try:
# short_event_descriptor = short_event_descriptor.decode("iso-8859-1").encode("utf-8")
#except UnicodeDecodeError:
# pass
try:
short_event_descriptor.decode('utf-8')
except UnicodeDecodeError:
try:
short_event_descriptor = short_event_descriptor.decode("cp1252").encode("utf-8")
except UnicodeDecodeError:
# do nothing, otherwise cyrillic wont properly displayed
#short_event_descriptor = short_event_descriptor.decode("iso-8859-1").encode("utf-8")
pass
if (lang == "cs") or (lang == "sk"):
short_event_descriptor = str(convertCharSpecCZSK(short_event_descriptor))
if (lang == "hr"):
short_event_descriptor = str(convertCharSpecHR(short_event_descriptor))
self.eit['name'] = short_event_descriptor
# Very bad but there can be both encodings
# User files can be in cp1252
# Is there no other way?
if extended_event_descriptor:
extended_event_descriptor = "".join(extended_event_descriptor)
else:
extended_event_descriptor = "".join(extended_event_descriptor_multi)
if extended_event_descriptor:
#try:
# extended_event_descriptor = extended_event_descriptor.decode("iso-8859-1").encode("utf-8")
#except UnicodeDecodeError:
# pass
try:
extended_event_descriptor.decode('utf-8')
except UnicodeDecodeError:
try:
extended_event_descriptor = extended_event_descriptor.decode("cp1252").encode("utf-8")
except UnicodeDecodeError:
# do nothing, otherwise cyrillic wont properly displayed
#extended_event_descriptor = extended_event_descriptor.decode("iso-8859-1").encode("utf-8")
pass
if (lang == "cs") or (lang == "sk"):
extended_event_descriptor = str(convertCharSpecCZSK(extended_event_descriptor))
if (lang == "hr"):
extended_event_descriptor = str(convertCharSpecHR(extended_event_descriptor))
self.eit['description'] = extended_event_descriptor
else:
# No date clear all
self.eit = {}
"""Module docstring.
Read Eit File and show the information.
"""
import sys
import getopt
def readeit(eitfile):
eitlist=EitList(eitfile)
print eitlist.getEitName();
print eitlist.getEitStartDate();
print eitlist.getEitDescription();
def main():
# parse command line options
try:
opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
except getopt.error, msg:
print msg
print "for help use --help"
sys.exit(2)
# process options
for o, a in opts:
if o in ("-h", "--help"):
print __doc__
sys.exit(0)
# process arguments
for arg in args:
readeit(arg) # process() is defined elsewhere
if __name__ == "__main__":
main()
I trying to use a Python script to decrypt a message. I have the cipher text (noted as FLAG in code) and most of the Python code used for encryption. I need to find the original plaintext message. Below I am trying to build a decode function into my Python code but failing (novice to Python). Can any genius help?
Here's the code so far:
import string
import random
from base64 import b64encode, b64decode
FLAG = '313312Mw16RXtNmlF2TVRmU1pIQxxmnTxtV1ZWV2JFOXBSnFwkVTI5o1ZGWxpXmxZWTVZmM1RWWyFwnFZ4Y0ZCWFJYUwjWRxJPVvA1p1NXTxpvRUbUWxROQ1RGoEpXmlxOY0ZWmFbdZDRVMVx4V2fwV2NGWvNmm1bXZUU5VVJdNVpWRVbNVxRJqFIjUzpTnGjVY1tSWFRXODFTMWRVUVpKVE1VWxtWRlsjYxZKV1pgWxZNV2tYV1ZmT1pGm3bwRxZXVvJ4UFZYRvRvnWjXVGfeU2IjWyFUVyRTVEZem1NdpGjvVxbmVTI5p2IjWxZwRXRVVyjipxZGZFNSMVZ2ZEZOnE1gZlBWnTVDTUZNqFRgVy1SqwZVVWfWWxxeWzZuRTViVyjWmFaiVvBWnVZdUyejVw1HmFtWMFbXUy1VqyJGVxpmRxwkVy5CV1IkVzpUnGtUY1tSp1ZeZFNwVxV4YUpWVGJ6RvJUVxV4VwZKWVFeVxpSnFalVxRGVxbHZEZOVlVXY1ZKRVZYQxpwMVJ4U25eVGNFNVBWmwEiWVZmVVNfOVVvRTVZVy5CT2JVMUVSnFbYVwVmVFV6Rw9wMXBJY0ZOnVJUVxbWVlVCWW1WqFZeZFJuM2tXVFo4MU1GVXxNVTxfY0VmWxZYQxNmV2j3U2feVw1GWxtVqwbOWVpmRw5XMVtSnHBUVyfSQ1xVMUpUV1JfUvNSVVZfOWFWVyf5TxZwnFZUVxpmMFZ3V2eiqFpgWxZNVzBQVwtCn2RfWwtvRxZYUxtSTVYkOW9UMU53UyjmnVJFWzVmVEZtZDFWp1ZdpFRvRlxdVy01V1pHWwZOVTxWTUZmnFUiWxZZMVb4UyjSV01eSw9WVEZtVWe1WFJgWy5SnFbWVy1Sp1NeZFVUnGRVY0U1VxZHNVpvRxbYWWjSV1JfY3tUWEJtU0ZSp1ZeTw5uqxJbVxRJMVRfnEpwSGtPVxtSYVbgQxbNnFV3VWfwU2NVoDJmMGRbVxZZqFpdZFtuMyMjVwZmU1ZeoEpVnTVfY0tSMVYjUwbNVw14YvJGU2NURxRWmwEjZVZSVVFfRyjWnEbZWvBaMFZGWzpwRFJmWwVmUFbgQw5ZV1V6Y0ZwTyJ6VwjWM0JtVDFNqFNeVxNum1b1VWjmMGRWoEpWmwJTYzbGNFQjVzpWRxb2TwpKYVYlZlBVM0JHV0U1WWRFNWjNRzA1VxtCn1UiNVtSV0ZeUvNaUVZdVwfUMVbVU2f0n1YiMWxVMvVHVwpmSVFeTxpWRUx3Vwo4qFNWWzxSnFJXVvJKUFZXUwNvMxbHVWjmnVIiWxtVMGRbVvFmR1VdOVpSnWtHVyjao1UjWyfuMwZXYvFKSFVcRw9wMU53Ywo1nE1fSzbWnwaiVTJepw1WZG5TRzBVWxROQ1pWVXtuRTViVvFmWVZHOXpmVxb2TxVaWxbFWxBWSEZLVy1mSGVGUxpNWFJIVvNCVw5HnEpUm1ZTYvFiWFVemENWVxb1U1RGTxJeWxpWnTxbYy1epxpdNVbvWGslWxVmU2VFOVVSmlVXY1ZKm1ZUSXtUMxb3VG5mTxZeSxZWnGtlUlFwpxVeZFtWm3AjVW5Co2JVMUtVnxJtUyjmM1RVWw9SmlFZU2jSV01IUxBXVEa0WVZOqFVemE9WWGteVWjwmVQjVXtVm2RYUxRCmFpcTvBWMDFJUWf0V2IjVyxWRyROWWjSpVZeUy1TRUbWVyfmU1QjTwpuMwZOVzbGVVZeZGxXVyj4TxV0V1ZUVxpmMGsiVGjmWWFEUxZNV2tQVFZVMVJdMVZwRw5XWwZmTVYlQzNwMU54VWfwVWJ6VzVmV1JHZEZmR1ZgZFVWnTxaYVVaV1ZHWxpTm3RYY0p4VFZdWvBOnE52ZUZinWNGoGxWVlVLVDFSqFNgWy5SV3tWVFVaQ05eZFtNV1ZhVyfemFbVVTFmV1V4VybSVxZeWTBtWEJtUxZmpyFGUxpSVzBmVxpSQ2QjWwtVnFZSYvNST1ZeZGxWnFV5TVV0T1ZgTytWnTxbVTFmm1ZdpFtuMUb5YVVmU1NGUzZNVlVTV0p4M1ZWWxpZVyjXVyjwVWIlmFZWm1ZLUlFVqWVIWy9NREZXWvBSR1YjSyfvRXtWTVZiTFZIRw9xVw52Y0ZWV1ZgTyxWRyQ0ZDFmV1RdmFZXR3tVWxRKmVZWWwpWnyRUY0tSWFZHNWFWRwbGV2e1WyJdSytmm2RTVy1aRVFeZFNmSEJFVxRGn1YjWwpTnxbfUyjKVFZeZGxTnGRVVGjwVFJdoFxWSEUjVGejRVJdoGFWnWteVTI4qFJWSzxVnTxTYvFiRFZUSyxZV1ZHVGjaVWIlmFVWnFJHTxZVqVxeTxRvRzBHVxtGMFbVMUxRnXtVVzbBqGFVWw9xRw52ZEo1nE1gZlFXnFbtVTFOV2RGnG1SV2t2VW5CSw1WVxtxSFbhTVU1WFbVVy9UnFbVUybKV1JXmFRVM0J2WW1wRyNGoE5NMEbMVwZSR2IjZFpTV05VYyfmWFZeZHNwMVZXVxpKVGJ6QyfWWEbtVwZmRxNdOVZNVxwiVTNCU1pFMVVTnFbOUyjiSVpdVy9TMVx5U25mnVJeoFZUWEJtVGjwpxZXSxpWmlU0Vy01R1bWWxpXnFJXUyjZp1UlQzpWnEb5Uy05V01EVvFXWEJXWVpWWFJXTxtuM1JtWxtCV05WWwpVm05VY0tSNVZIQxpWRw5GU1pOV1ZeWxtVqwZPV0ZSp2JGZFpWM2okVyjSQ1xWSzZNVxbOV0paVFbeWwfTMVZ4TxZOVw1YUTJVVlw0VwpWqFxfSxZuMUbDYVVwS2RfZEtwRxJXVyjemFZfOXNwMytXVGjaU2NGSzVmVEYiVxZwWE1ERxRNVlxdVy05NFUjWwZTnyjXUyjmM1ZFWxbZV2RGZEpWU1ZFWw9XV1JHUvFGp1ReZG5SnEbeVFo4MU5WWxtxSEbOVye1WVZIRTFWMUbZUW5mVVZeWytUVVbtVyjmp2JGUxpNVzBVV1tGNE5HVXxWm2tQVxtanFYiZGxTVyjdU2e5nWNVVytXmw5hVwZmRxNdqFpWRXBQVTFmS1pGVzpVnFZXVvJKMxpeWxpNRw52TUpKYVJVNXVtVlxHTwZep2JGZFpWm3BXWvBwR1peWzZvRE5WTVZmpxZESwfwmlFXVWjmTyNfqEtWMVJPVvFGqFRXTxRvRwb3WxRKmWQjWxxwRTxVVy05mGFVmGFunVbHV25WVxbFNVRVqwbKWTJwRyJGUxtSMwbTVxRCYVQjUztTV1JXY0U1UVZcRvBuRxV4YUo5V2NFNTRVMvVXV0ZKWVFgWxtWRWf4VXbGMFZeWzZwRlxTV0VKWxpeWxpwnWjHVWjmV2J6RyFUVEZtTUZWWGVIZFVvRVbXVy5CT1ZWWxxVm3RXY0ZVMVVcRw9SVwb2TxZSTxJgUvBXnFbhVDFKpw1YmFBWV0bWVybBMVIjWzZWnUZXUyjKWVReVvRmVwbYWW5aVw1WSwRmnwJtVy1wSGNHOVpmRxwkVxRGo1YjWwpTnytUYvNSVVbfODFwRyR4TURGVE1VNVpUVytXVwZmRxpgnFpWRUbaWxZVMVZfZEVRnFbOY1ZKSxZUSvRNRxbGTxVmTxZYUxZWnwJKWVZmp2JGZFRvVwbIVxo1V1ZGSxtuSGRXVwVKnFZGWzZZV1bGWWjKV1YkpGxWVEJlVTFVqGREWxVuM1JeVWfmYVRGVXtVm3RVY0ZiV1bVZHpvRxbVUxpGVw1fSzZWM0JPU0ZKp1VfVy1vRxwiVvI1R1UknFpXm1ZTYvNaVFZcQTFwRyj1UW5moFIjSwxUMVZLVyejRVJcSxZNRxbaVvBmMFZeZHpUnVZOYzbWS1YlQxZOVyRXVGjwVWNYUzRUVEYiVyjmVVFfOVNvSFJKWxROo1ZGSxxVnFZVVxZmpWFVWxNTRTVVUWjmV1ZeoE1Wmwx4UvFOqFNeWy1SMwbXVFZwo1RGVXxxSGRXVvFKSFZIRTFmVwbXV25wVyIkqEtVM0J3Vye5WWNHNXBuMXBPV1o1T1MjWzpVnFbVYvNST1bdZFNZMVV3YUZwWFJeRyttVWQiYvFmWVVfqFZum0bYWxRGn2VGTzZwSEJXVvFKS1peWy9ZVw53V2fmTxZeSxRmnFUiTVZmR2JGTxpSnGjaYUVVMVZGSxVSnytWTVZmM1ZdWxNTVxJ3VW05V1ZWoEjWM0JXVTJap1RgWy1SWFJeWxROo1MjWwpXnE5TTVo5mxZHOWFumlF2TxU5VxbFSvNmVVbHVvFGpyFGWw5SMwaiVxo5V1xWZEpwRyRgUxtap1ZdWyFTMVJVUVRWVxZdNTNWSEJhYyjwRw5WWxZWnFbaVTI4qGQjoEZuRxJTTUZiVxZfNUNOR1Z3VGjeUyIkqGFUVEZtVEZWp1ZgZG1vRwbHWvBWMGNGWwZTm2RVVyjmSFZeWw9wnWRGU21WTxJenlBWMVJDTUZOR1ReWw5TR2tVWxRKmVRem3pWmxJfUyfmV1RWVvBUnEbVUWbWVw1WSxBWVWRHZGejVyRGVxpXRwbLVvI5nw5WTztUV05UYzbWp1ZeUwpORxbVUW1WTxZURxxXm1btYvFmpw5VTxtWRVbaWyfwV1JWRzZwR1ZXYzbFqxZYRXtTnWjHVG5eVyNGSzpWnGRkWVZmpyJIZG5NVTVJVy5CU1UkVXxZm3RYVwVdMVpWWw5ZVwb2Y0ZanE1fSvVWRlxlUlFOWFZemFtuM1JVVWfWYVRGoEZXm2RSY0ZKV1bdVvBWVxbWTxV0WFZeoFBtVyRTVxZOpVJeWyjNVXAjV2fmn1UjTXtWV0bVYyjmVVZcRwZNVxV4VybSnGNWSxpmMFZlWxZmVVJgWxZvRwbEVwtCR2RfVwtuRxZfVwZmT1YjUwJZnWt4VW5wVxZGWxVmm2tDU2jwqWRFpFRSnTxaVFZvqGJdMXZOVyjmY1RWWFZdZFpXVw52ZEo1V2IlQXbWVEZTUvFSp1VeWy9NM0JtVFZmWxwjWxVTnTxUTVpaMxbdYlFXnVV6UWf4VU1XmGtVMVV4ZG1WSWFGTy1WWE5bVvNCV1bWVXpOVxbgUxRWYVRUSyxTRxx5ZEVwVWNGoEpmMGQ0VwZmWFVdZFZum0alVwVmT1ZWTxVVmlVXVvNzMVZdWyFmVwbXVG5wYVJXSxVWm1YiV1Zep1ZgTzBSnGjbVwo4qFpdMUZXmw5WYyfiUFReWvBSnFbZY0ojTxNHqE1WVEaiZDJmWFVdVxNuqxZYVWjaQ2RGWwpWmwJOUye1R1RWVyxWRxx4UxRGVVZWVyxWm1bTU1ZGpw1XVxNuqxYjVxRGU1EjUxZNWFbeUvNSVFZgRzNTMVJYZUtOn01dMWxVMvxtVxZmqVFdpFtum2jbVTFVqFJdMVxvRlxeTW1KUFpXNU9WMVbWTVZmWGJdSxtWnFbtVGjVqFVdZE5SMHAkYVVwNGNGSyfvRWtYVzbWWFZFZFNTRw54TxZWU1ZFWvNWm1JPUlFNqFZXRw5XRzB2WyfmS1MjZHVUnE5XUyjKV2FVmHpWRwbVUy5aWxbFSvNWMGRLV1Zmp1ZeTxpWRVblVyjSS2JfnHpUnGtTY0p4V1RVmG9OVxV4V2e5oFZeoEpmm1Y0VxZmpyRFOVpSVxalVTBmUxbGTzZOVxJYUyjiV1ZXNUfWMDFXU1pSVyIkSxZUWEbTU2jwp1pfOVZWmlU0Vwo4MWJVMVxRm3tXVwVKqxpWWzpwVxb2ZUZOTxIko3tXVyMjVDJWp1JeZFpuM0JtVFVmYVQjm3bwRXRPVyfemFbUTzNWVxbZUVpOV2IkmFBWnwJLV0ZOVVZfVxNWnHAjVvNFp01WTzpXnFbQV0tCVGFXOWFUnGj4WW1GVFZdNVpWnwaiV2ejWFVdqFZum0a2VFZmYVJfVwpVnFZXTTJ4SVYjY3tNRw14YUtmnxJGWw9UVVJHU2jiR1peTxRuqwZYV2fWNGIjWzZOVXRWWwU1VFZdWzbZMDFWZUZSV1ZFWwVWVEZTUvJmp1pgWyjSM0JRVyjaQ1MjWxVRV0bTUye1WFZHOTBWR1V6YwV0V1JXYlFVqwYiV1pmRxNeTxpuqxZQVxRKNGIjTzpUnGtPVxViVVZeUwpUVzBIWWjKT1ZdNTNmMFY0Y0Zmp2REVxZNR3slVyjmT1pGVzZOVlVTVyfiMxZYQzNTMUb2TVtwYVJXSzVmm1YiU2jepVFfRxRNVwbYVxtKp1ZfVzpXm3tXUyjiU1ReWzpwnVV6YwZWV01YUw9WVEZtUlJzqFNeWy5SnXtVVFRGS1ZWWwpWnTxVY0VemFVgQwpWVxbYWWfwVw1WWytmVyRGWVpaRxpeoE5vVTQkVxRJqFMjUzpwSFbtTTJaT1ZemFNTnGR2VyfwVWNFNVpmm2MjVwUjRVJdMVpSRVb6VTNCMFNWWzpWnTVOVxRSmVZWWxpwMxZXYlJKnxJYmFRUVxUjTxZWqWRFZFVWMGjdVTNCYVpdMUxRV0ZXVwVipxalQw9TRwb3VWjaU1YkqFZXm1bXTUUjV1ZgVy1SqwZ1VFRCYVZWVyfRnxbiY0ZemFUkOTRmVwx3TxRCVw1cRxBVWEJPUy1VqyNGZHBuqxZKVvFwM1xfnFpTnyRWYyjmWFYiWvBWnFJXVy1WVGNGWvJUVyRlVwZZp1pemFVWnXtPYVVmU1pFOVZtRzBfY0ZiSxpdVyFVMyt3VFpGTxYlQxZWm1ZLVEZmVVNfOVpWmlU0VxtCU1bXVXtWmxJXYyfmWFUlQvBWmlxWVG01TxIkSxbXWEUjVG1eV1JeWy5SRUbVVFVmYVpem3xZm2RVTURGV1bUTzNuMVbdVybmV1ZFNVtmVEZLV0ZmpxpdNVNXRUbOVyfSS1xWSxZNVxbOV0ZmVVbeWxbZnGf5ZUpWV1JgTybUVxZlVwZwR1pdmFpSnHBQVwtGS2VWUzpWnEJXTVViSFZGVy9uMVJHVGjaVxZFWxVmVEa0TwZmRyJFZHBvRzBJVDFWNFUjWwZwRyjYVwU1TFZdWxNWnE51UyjSV1YkSXtXVEbbVW1eR1NgZG5SM2t0VFZVMVMjZHZVnyRTTVViMVVgRvBWRTFIYwtwYVJfmFtVmwZXZUZiSVNeUxNNVXBIVy05V2QjWwpvMwZhUvBmVFRVWyFRMVV4YUU5nWNGoFpmMFY0VTFmWVFdpFpWM1JIVxRGT1pGVzZXnFJfU0VKqxZURy5ZnE53U1pKVWNgQxRWmwEiWWjeqE5VpFpSmlVXWvBSQ1ZdMXtVnxJWTVZiWFZdZFpwnWjGZEZWV1pFSwbWM0JWWW1mV1NemFpuMXBTWxRKmWRWoFpXm05VY0U1WxZfOTRWVyRGV2jWWGIjoGtVM0J6WVpaRyVGoGjNnUwjVxRKmVUjUzpXm1bYY1tSp1ZeZHNTMWRVU205T1ZeSxpmVVUjVGjKWVFeUxVWnFx3VFtCVxxWWzZxRlxTTUtSWxYjZDRwMxZ4VWjenxJXqE9mVEbbVFZWp1ZfRxtSnxJXVy5CT1YiMUxVmlxYVwU1M1ZWWwfwVwb2V20jnWIlUxZWVxbXWVZeV1ReWw5SRVbVVybGYVVWnFtOVTxUY0Zem1VXOVpXmlF4VWejVw1WSxBUnFbOWVpwRyRGVxpWRVbPVvI5o1YjWxtUnyRVYzbWYVRWmENwVxb1UWe5VGNGVytUVytHVTFKRxJcTxbum0alWxtGV1pGWzZXnFJTUyjimxZURy9SMVZGTVVmTxZeSyFmnFJXU2jwpxZgZFRNVTVXV2fmU1ZFMUVRmw5WY0ZmmFUkOHtWMWR5Ywo1TxZYUXxWVEwjVTFmR2MkTxVuqxZPVFZVMVRGVzpVm2RfY0ZWmFVfOTRuVTF3U2fwWGNGWxtWnFbPV0ZKp2FHMU5TR3tMVyjSSw5WTzpvSGjfUxtapxVgQwbNVxV4VxpKnVJeVytWMvVDVGjZp05URxZNVxb2VyfmT2RfWwtwRxZXUxRWUFZUQxpwmlFHVGjWVGJ6VxtVMFbtVxZwVVFgTw5SnHBKWyfmYVZGWwZuqwJmYye1nFZdWw9XR2jGV2jiTw1WoERXm1ZhVTJap1VdWy1SM1J2VvBaQ1RGZHZuSE5hTVVemxUkNVpVMxb3U2jmYVZfZ3pVM0J3ZG1mR1ZeSxpuqxZQVxpSR1xWTwpTnFbgUvBmYVRWZFNUVxV4YUZwWFJfmEbWRytlVvAjpWNFoFtWRTUlVwtCT1YjTxVSnFbXVvJzqxZdWzNTMU53VGjmU2J6RzVmm1Z2TVZVqU5WTxpvRXBJVGjWMFbWWzZOREbtUyjKTFUlQyFWnGR4ZEZWV1pGRytWMWQlWWjSR1VemFVunFblWyfvNU5GVXpmqwZUTVo5mxpdY3tXR1V5WW5eVw1WWvNmm1bSWTFwpyRFNWjmRVbZVxo5V1xWZEpUnyRgUvJ4V1bXOUfTMVbXV2e5U01eSvNWRlxLYyjKV2RIWxVvRxbeVTNCVxxVMVZNVxJeTWbzqFYlRTFVnWjHV1pKVyIlmGjWnGRbU1ZiRxpeZFNvVXAkWxVwmVZVMHpwR3tWTVpaUGFFZE9wMUb3UWjSVFJdoEfWVEZlWVZSpw1VnG1SnFbVVyfWYVpWnHtxR1ZeY0ZGmFbdVvBWnVbYVWfaWw1gmHbWSEJPZVZmWWJHVw5WnHBIVvI5U1IkVXtTnGtXYvFiVVbUSyxwRxbHYwV0oGJ6RxxWRlwiVWjmWVVXSxtvRxbeVxRGqxwkZEZvR1ZTVyjiV1ZUSyxUMVJ4U1pSWGNGWxpUVVZtUvFwp1ZUUw5Sm2jaWyfWYVUkVXbRnFZXY1RBqFRWWxZZMVJ2TxZanVJUVw9WRxZXZDJWR1pXSxVuqwZPVyjwmU1Wm3xZmlxPVye1NVZYQyFVMVx3ZEV4WFYlmFtWMVbLZFZOpVFfNVNWMUaiV2fmo1MjSzpvSFZXYvJKVVZcRyFXVxbWVyfwVGNGSxxUMVV4V2ejRxpdoFpNnyt6VTNGV2RfWwZwSEJXWwZmUFZURyFuMU15VWjwVWNGSxVmnwJLVEZmpVRgZHBWnFZaVFZWNGIkVXbRV0bXY1tapxbdWxJZV2RFUWjinVIjSxpWVEZXTUZVp01WnFpXR3tWVy1SV1NGZHpuRyRfUyfiWFUlRTFWRxbYVWf0V1JeSwRUVxb2WVpeSWFGVxNNRFY1VvI1Q1ZfZ3pOVyRXYzbWVVVeUwpxRxV4VWf0nGNVoDJmMGRbVWjmWVFXRxpWRVb2VvNCT1ZfmEpVnFJfY0ZZMFZdWzNRMU5HYvJSV2NYmFRWmwEjZVZmRxZgZG1SnFwkVxo1S1pfVzZXm3tWTWbGUFUlQwfXVxZ2Y0ZWV1pGSxBWMVJCWW1eV2FIZFVuqxZYVvBmMFYjVxpWnyRTY0o5mxYjmHpWRxx4V2jeVxYlmDNmVEZTVy1eSWRGWxpWVzBMVyfmYVMjUzpuMwZOU0p4VxZeVvBTMVV4VxpKn1JdWxpmm1ZLWxZKV2RGUxpum1b2VTNCMFJXWwtNVytfUxRWMVZUSvRvMU14V1pGn1JFSxtWnFJ3VGjmR2FFpE5WMVa1VwtCU1ZGZEZTV0bXVvJKpxbgQwfXRxJ3YwZSV1YkqDNWnTVLWxpepw1WZGFTRzBVVWbGS1Ejm3xxRyRUY0tOm1VfOTBVMDFYVWjiVw1WSwjUVxbtU1ZOp1VfOVpXRUbQVyjwmVQiNXpUnGtVYvFiWVVeWzpOVzBHWvJKWxZdNUxWSEY0VTFmRyRGnFbWM2RbWxZmT1ZWRzZxRxJXVwVZqVpdZGxUMDFXU1pKnxJYUyjUVxbtUlFwp1pfOVpWmlVGVTI5MFpfWzpTnGRtUyjmM1RVWxZZnHBHV2jSV1JUVxJWm1bXTTJeV2IkSxVuMDVVWxo5YVNGm3bwRTxVTURGV1aiVzNWVTB3ZEU5Vw1WWTBtSEJPZG1wRxpeoE5SnHBNV1o1Q2QjTzpuMwZOVxtSVxVcQTFxVxb2YwV0Vw1EnFxWnTVDVwZKVVJemFZum3BQVwtCS2Ren3btRTVXV0p4R1YjUwfUMU15VGbmU2NUVyFUVWtDUlFmR1ZdZFVWnTxdVy04qGIjSzZOVXRYVwVmmFZFWwfWnWjGZUZSTxZYUXxWVxbtVTFOp1pdWy5SMwb3VybKU1NGWzZuSGRVUyjKWVUkODFUnEb5UWjWWGJdSvNtVxbXZVZmpxxfNU5NRzBWVxpSQxxfVxpTnGjUYvNaYVRVmHNORxZ2YUU5VxJdNTVWSEZ3VyeiqxFdoFVWVxZbWyjwU1pGVzVWnGRUUxRWVxpdWy9VMUx4Vy5wYVJVoFVWm1UjVVZVqU5VNXBSnTxaWvBWn1ZHWwtVm3BtUxpaS1RWWzZZV1ZIWWjmTxJgUw1WnFJLVDJaqFVgZFZvRwbVVTBmS1ZWZHxwRw5VYzbGR1pfUwpWRwbGZEU5Vw1gmGtmVEZHVy1WRyRGoE5SRVx3VxRGn1YjWwptRWjYY0ZmYVRWWwfOVxbVU205nE1VoFxWnTxXYyjmWVFgUxpSnXtMVTI4qGVWVzxXnTVfUyjiMVYkOVpWMxV5VyjmVGIlUyjWnFJ3TwZmRyFFOVVvVXBHVvNGo1UjWXpOV3tWTVZiUFRgQw9SVxJ3YwZKnE0iSxpWVEZgTVZNqGIkUy1SWEJVVyfVMVIjVyfRnyRUVyjKWxUkOTBWRxb2TxU1WxbFWxBUnFbPZVZWp1RfVy1WRxbMVyjSQxxfWxpTnFZUYvNSVVbUTwNwMXBHYUZwU01WoFpUMVV4VxZmWFVeVxpNRxb2VyfmU1pHnEZtRzBOTVZiSxZYQy9VMDVWTVtmnVIkSxZUWEbDTyjVqFpfOW9NVXBJVwtGMFZHVXtXnxZXYyfmM1ZHOHpZnFJ2V2jWU01EVvVWnwY0YlJmR1VXRxtuM2tXVFZwU1RGVXxxSHBPVvBmMxZWmHNVnFb3U2bWV2NHqDNVVEZPV1ZKqGRGUw5SMzt6VyfaMFEjUzpWV05UY2jmVVZeZFNTMVV5TxZOVFZeSxZVMvsjVGjKWGQkRxZNnUbQVwZwT1pWUzpWnTFOU0VKo1ZeUwNvnWjHVGjWU2J6VxxVMFaiVyjiV1pdOVJvRTVmVy05NGIjSxtVVEZtVvNaM1bdWxJZVyR2YUZinGIjoE5WVEJhVDAjV2IkSy1NM0J0VFVwo1QjZHpWVFZiVye1MxbdZDBuVxbZUW5SWxZFSXpVnwIiVye5SWRGUxpSVFZSVwZWo1RfZ3pNVxbgUxtaVFRWZFNTMXBGVy05VGNFMWtmm2RlVvAjWGJFpFtWM1JYVTNCT2VGUzZOVxJfUzbdMVpXNUNVMU53Y0teV2JeoFZWnGtCWWjepVFfOWjWnEbZVwo5YVbWTwtZm1JXUy1aWFZdZEpwnVZGZEo5V1YkqEtWMvxTZDFOqFVdWy1SVFZYVyjwmVRWWzVSnw5VY0U1WFpdZHpVMVx3TxVwV1JfqE9tVyRKWWjKpw5WUxNWRVbQVyfWU1MiNVpXm2jUY0ZKVFZeVyFSMVbYWWjin01VNVZVMVJXYy1mpw1UUyFSnHBYVWbGpxxVMVZUnFJXTURWUFZUSvNZnVZ4VyjanxJXqFpUVVbtTUZVqU1WSw9WmlFaVy05o1ZGWxxVm3RXY0ZVMWFWWwbZMVJ2TxZWU1ZdoDJWVEZXWVUjR1ZXTyFSV3tVVTBWYVZWWwpWmxJeY1ZKWxVXOXpXmlB5WWf4VyNGWzbmnwJTVy1wRyVGQxtSWFJPVxRGV1UkmHtVnGRVYyjmnFRVWyFUVzBXWvJKVGNIUxpUMGthVxZmpw5YVxZNV3tMVxtCUxxXVwxwRlVXYzbWTVZdWxNRMUb3V2fmnE0lQxVVnVJ2WWjmVVFeZFRvRwbYVTNFMVYjTwZwRXBXUyjmmFRWWzZZMXBHVy01nVJUUyxWVxbXVvJmR1NemG5SWFJPVvBmWw1eoEZVm2ReY0U1NVUlQxNuMVbZUVpGWFZFWzZVVEZPU0ZOpyRHNWjNmlQiVvFSSxxfnHpWnxbTYvNapxVfODFxVxb4ZUo5nGNWWxpVM0aiVy1WpxpdpGFSnHBQVwtCT1pWVzZxRyRiYzbWTFZGUwpUMU15VWjaVyJdWxtVnGRlZFZiR2FGTxNvSFJXVy5KR1ZHWxZwRTxYY1tapWFWZFpWMVJ2U2jSWFIkSvNWWEJhVTJap1NXRy1SM1J3Vy05S1NeZFVRmxJhTWjKWFUkOUfWVxbYZUROWGJdSTBVM0JPV1pmSVJeUy1Sm3BQV1tGNFxXVztVnFbOVxtaWFZeWyFUVxV4V2fwV1IioDVWM0JXY0Zmp2RFqFtWM1JYVXbKU1IjWzZPVTVTVvJKqxZfNU9ZVw5GTVZmnVNGSxxmVE5SWWjVqU5VOWjvRyjaYUVWp1bWSxpXm3tXUyjiUFbYRwfWnVbGZUZwTyNGnlJXVEZXZDFSR1ReVxVvRwbYVWjwNE5WZFVTV0bUTVtSV1VfOTRuMUbZVVRGWFZFSytVM0ZTVyjwpxpdNVtSnG96VxRCn1QjTzpwRVbXY1tSnGFXOUfURxZdUVRWU01VoFZVMvt4YxUip2RGZFZNVxbYVFVmSxwjUzxTnFJXTUZiUVZGWxpmVxbHVGfeUyIioFVWMFbtZFZVqFVdTy1vRwbXWxVWmVZVMHpwRXRVVvNwmVZGZE5ZnE55V2jSnE1fSwjWMvVLVDJeV1ZgWyFmRVbVVyfWYWVWWzpuRw5XUvFKWVZIRwpUnEb2TwRGVw1XmEjWSEZPZGejVyRGoE5TRUbLVvNCo1YjUwpUnyRXY0VKpFVeZHNvMVb1VG1GVWNFNVpWnTwiYy1mR1pdTxZum0bYWxtCU1JWTzZvRTVOVxRCmFZUSyxUMWRIU25eV2NGWxNWnGtTTyjSV2FHOW9SnEbXWyfSR1ZdMUVSnFZXVwVdqFRVWxZmR1bIZUZOV01EVvVWSEY0ZDJWp1NeZFZuMzteVWbBMVZem3xZmlxeY0tSV1ZgRzpmVTF5VWfiWFZeoFBWMVbPZG1mRw5WZFNXRUajVyfmV1IjTzpTV0ZeTTNSVVZdVTFVVyR4ZDJKVGNGnGttRVZ3WxZKWFxdoFZNV2tQVwtGV1ZdMUxtRxZYUxtOmxZeZDBWMVJIVW5wVWJdWxNWMFV4TyjWpxb6RxRvSEJYVvFao1UkVzZXnxZWTVZimFUjZFNXRxb2V21WVFIkSvFWVEZhVvFWRw1VWy5SnEbeVFZVMVRGZHZXmlxfUy1aMxbdVTFUnVV5VW5WV1JfmGjtWEJPVvFiSGNHNU5NRzBSVxRJMVQkVxpuMxJfU0tCVVVeUwpUMVbGVy5KTxZdNVbVM0JTYvFmWVVdZFVWnHB2VWfmT1pGSzpRnXteTVVZMFZdVy5OVTFHV2jeV2NYUxRWm1ZLVDFWm1FfOVRvVwbXVvI4qFReWxVSmwbtUvJKSFZVWzZZV1V6YUpWTxZeoFBWRxZWWW1eV1RemFZuqxZWVTBVMVUjVxpWnUZmVy5SSFpdZDBWVxbGYzbCVVZeWvNVM0JPV0U5VxpfVxNmSEJEVxRKmVMjZEtUnFbfUvNaUVZcRvBRMVbVUy1Gn2NFoDRWnTVHYy1VqGRGVxpum2jbVTFmMFYjUzZtRxJeTW1KTFpYRvRwMxV4VxpGnxJYUyFUWEZTVGjmR1VdTxRvSFIkWyfwp1ReWyfWm3tYVwU1M1V6Rw9XVwb2ZEojV1YlZ3bXm1btYlFOp1ReWw5XRxbVVWbBME1WVXxZnzBiVvBemxaiVvBWMVbVY0RWV1JeWytUnFbWWVZKpyRIQxpWVzBMVwZST2QjTwpVnGtVYyjmVFZgSwNWVxbHWzbGoFZeWxpWnTsjVwZmRxNdOVVWRUb5YVZVNVpWTzZwRyRTVwVZqVpXUwpUMDVXVWjeVyNGSxtUVxZLTxZVp1ZXSxVvRwbJVwo1R2JVMHtwRxbVTVZmnFRVWxZZMXBIY0ZSV1JXOHtWM0ZbWVZmR1RdmE9WMFbVVvBmYVRWoEZWnTxeY0UjmFRWZHpuMVbWV2e1WFZFRyxmqwZLV0ZWpyRHVxtSVFUiVyjSQ1xWUzpUm2jXYyjipVRVZGxXVxV4YwZwV1IjWxpmMFZtV2ejWFVeTxZNnyslVwtCR2ReWxxuRxZYUxViSxYkOVpwMUx4YUtwVWNUVxVVnGtDVFZmRVFgZFbWmlVXVW5CV2IjSzZOREZWVyjmWFZURxNWnVbGTxZiTxIkSXtWmwaiUvJWWFNgnFVvRTVRVyjaQ2JGZFtNVlxXTVU1V2FFWwNVMxV5WW5WV1JeoFBUVxbtU0U5WWNGTxtSVzBWVybGVxxfnEpWV05YYyfmYVbYRyxURyf5WWjKoFJdMWtWnTx3V2ejpyRFpFtvRxUjWyjmR1YjVzZNVlFOUvJKTVZfNUNNRTFHV2fenVJURxZWmwZtVVZdqWVIWzBSnTxaWxVWn1pdMUZXmlFWY0paUFbfODFTVw52Y0ZWV01YUTJWnFJHYvJaV1NgmFVunFbVVFRBqE5GZHVTV0bVY0UjmFQjVTFWVwx3TwpKWyNHqEjWm1bPV0ZWpxpeoG1WMUbPVxRGn1VdMVpVV0ZiUvNSpxZgQyFTVyRYZUtwU01eSwtWVlVXYwUjSGJIZFpum1bEYVtCVxbGWzxWnFJfVxRWUFZWWxpwMxZ3ZERmVyIlUxVUVyRTUwZVqVxeTxRvSEIkWyfwmVUjWxtZV0ZWTW1KpxReWw9WnWtHUW01nWNGWTBWVEZgWWjFqFReWxNuMHBVVybGYVVGUxZWnyReUyjem1aimDBUnFbVUyejVyNURxtUnFb6WVZwp1RfVw5TRUbQVvFST2QkZFptSFZTYzbWV1bURyFwVxbHYUpWWxZdNVxXVE53Yy1mRyMkSxbWqxZQVTNCWxbGRzZWnFJfUxRWTVpdVyFVMDVIU25mnVJdoFpUWEJ6WWjSV2JGZG9WmlVZVwo5S1pdMHtTnGRWY0ZZMFUlQvBWMWf6YUZSV1JYUwjWnTxlVTFmp1ReWxtvnxJPVFRKmU1GWwptRTxVY1U1MxRWWxNWVxbdY0U1WGIjSvNmWEJPVxZGqE5WVxpWMztNVwRGV1xWTzZNVyRtU0ZiVFRVmENXVxV5TxZOVE1WnlJWRlwiWxZKSGFEUxZNVwbMVwtCYVNWUzpWmlVXTURWo1ZGVyFuMVJ3VGjWU2JdSzRmVE5lU2jSV1ZcQxRSmlUlV2fWmWJfnHZXmlxWYyfGmVbWWw9SVwb2ZEZSV1ZeoE1WVEx4VvAjV1JgWxpvWFJtVFROQ1RGZFtxSGRfVye1VxUkODFWRyRHV2jWWFZFSzbUVVbtU1pmRVZeUxpNVzBWVy05o1YkVxZOVxbgUxtCYVRURyFTRxV4YUZwU1YiNVpmm2RlVyeip2RFZFVWqxZYYUVmR2RfWwVSnFJUUyfiTxZdUwNTMU52TVVmnVJgQxRmVlxtVDFep1ZfRyjNVTVXVFZWMFpdMUtZVEbWTWbGTFUlQvBwnVbHVyjWV1bIQwfWMVJPVvFSp1ReZFRvVEZPVWjwNE0jWwpmqwZOY0ZiSVZIQxNuMxbGTxZeVxZeWvJtVVbmWVUjVyRGWxpuqxZbVxtCU1IjUzpXm1bYY1pKpxZemFNOnGRYZEZwVVZeSxxWRlVXYwpVqVxeVxtWRUb6VWbGp2VHmEtZnGtfVxo5mVZfNUNwMxbHVVpOnxNIUxVWnwZTTUZiR1pdpGjvRTU1Vxo5mVUjWzZTm2jWTVZWmVZIQxNTRxJ1Uy01U1YkSvJWRxbXWxUjR1ReZGFSVEZVVy04MVMjnFtxRwbiUyjKSVQjVvRmVyRIWW5eVyNHmEfUVxbKWVZiRyRGUxpmRxbEVyjSQxxeUwpVm2tWVwZmVxZeZGxwnHBXV205VFZdMWxXm1b3VwZmWFxdOVZNnyteWxZwV1ZfZExwRzBeWwVVqFZURy9WMVZHVG5eV1pHqFRWnVJXTyjmpxVdZFRNmlQkVW5Gp2JXVXxZnxbVY0ZiqxZGWw9WnFZ5V205U2J6UXtWVlVPVTJWVw5WWy9SVFZVVFVSo00jVXxZmlxeY1ViMxbVZGxuMVx3TxVwWFZFRytUVVbKWVpmRVJeZFNWMwbWVy5Fp05WTXtwRVbXYvNaVFZdVTBZVyj1UW5wVFJeVyxmVVJHWxZOR1pemGFSVzBQVFZmMFJfZEpWnTFOUvJ4TFZXNUpmV2t3VGjWVGJeWxtVnGRbZFZwVVNdOVNvRlxcV2faS1ZWWXpOREZmVvNaM1UlRxNWnVZGVy1WU1YkSvRWmwa0WVU1V1RXRw5TR2tVVyjaQ1MjVXxwMwbXUyfmV1bdZDBWRyRHU2f4V2JdWvNVMvt4VyejVyFHOVpSVyjbV1o1T1bWWwtVnFbYYvNSV1bXUwpUMVV4YUVwWFJURwpXVE5lVxZmm1ZdqFtWnFZbVWbKU1NGUzpuRlVeWwVmTVZERzNTMU5HVxpOYVJeSzVmm1Z2TVZwp1pfRxVSm3BYVvI5p1bWWzZOVEZWTVZKQ2FESwfwnGR4Y0U5V1pFRytWVlVHUlJaV1RgWy1SVFZTVyjao2RWZHVSmlxiVyjiRxVfOXNVMVx3TxteV1JWWytVqwE1V0ZwpyNFNVpWRVbXV2fWYVYiNVpvMwZYY0Zmp1ZcTzNTMWR3VxRSn01VNVxWRlsjVvFwR2RGUxVNVxx3VFVmT1NGoEptRlVfUxtSSFZYRvRZV1ZWTVZeUyIlQyjVnVJ3VEZZqU1VZFpSnWtXVFZao1ZdMXpvMwbVVvNaM1ZgQwfXRxJ2U2jKV1ZgUxVWnTVCWWjOp2RGWxBWWGtWVyjwmWRWVXxxR0ZeY1ZKV1YkNUNXmlFFUyejV1JfmFBUnFbLZGjdqyJGoE5unFbNVvI5YVQjTwpUnGtVY1RWT1RVZDROnFbZZEZOVFZURwZVnwbTYvFmp1NdZFZNVzBaWxRGYU5eUzZwRxJOVxRWV1ZWWy9VMVJ3V2feVGNGSyjUVlsjYwZVqGFHOVpvRTU0Vwo5MGJfVyfSm3RtUyjiUFVYQw9XVxb5Y0ZOV1JYUxbXVxJDZDJmR1pXSxJuMytXVFVao00jWXxxRlxTY0U1M1aiZHpmVTFXV2fiVVZFWzZVVEZPZDFWpw5XMVpXRUajVvFSQxxfnHZNVyttUvNSVxYiVyFWVxJWVy1GVw1ERxpmMGt3VyejRxpdTxZNVwbIVvBmp2RfZEZwRxJYUxtSUFZURxpOR2tXYUtmnVJUVyjWnFbtZDFmRVFcQxVvRlxdWyfWn1ZHWwZOVXRYVvNaVFV6RxbZMWR2V2jiTxYiNDJWm1bhUlFSp2FFnFVvRxbtVFo1p1ReZFVTnTxUTVU1WxVfODVuVTFIYwRSV1ZFWzbUVxV4V1ZmqWFGUxNNRlt4VxpSQ1YjTzpvMwZiUxtSVVRWVXpZVzBHVWfKTxZeoEpmm1Y0VWjZqFpdZFtuMzslVwVmSxxXWyfWmlVTV0VKVxYjY3pNVw14ZEZmU2J6VxVWmwEjZVZmpxZgTyjNRFZXVTI4MVZGWxxuRFJmWwVmWFZIRw9wnFb2ZUtCV2NGnlFWnGQlWWjJqVVeVxNuMXB0VyjWYVNeUzpWnUZUTVZmM1pdVXtWRxx4V2jSWyNYZlBVMVV4Vy1aRyJGoE5NVzBJVxRKmVYjVwpVm1bOVvNCpxZeWvBURxbVU2e5n1ZdNUxVMvVHVwZmqVFdMVpTSFJYVwo4qFNXWwZUnFJXUxZiUFpYRvRZV1ZHVVpGnFJFSxpUWEZTTUZmR1ZgTw5WnWtHVyjao1ZWWXbuRXRYVwVKM1bURwfXRxb2V2e1nE0iSwjWWEJtVTFJp01YnFpvnHBUVFo5MFMjVyfUnE5XVvFmV2FFmHpWRTFFY0RWVw1gmDNWSEZKWW1wRyVGTxpNnEbIVwZWU1IiNXpUm1ZVY0p4VVbfODFWVxb4TURGVE1XOWbWRlwiYvFKpw5VOWFWnFalVyfmU1pGZHVTnFbeYvFiVVZURy9UMxb3VG5eVVpIUxRVnVJXUlFwV1pfNU5SMUbGVTI4MVYjWxpXnw5XUyjmmFRVWyFTRTxWZEZSV01GoERWWEZbZW1eR1VeZFZuM2teVWjwmWQjWXxxSGRVYzbGMxRVmG9WRwbGV2f0VVYlZGxWm1bPZGjiR1VeUy1uqxYiVvNFp01WUzpTV0btUyjmpxZdVyFSMWj3YwV0V1ZUVxpXm1ZtWxZmV1pdMVZNnyp3VxVmS2VWWxxvRzBOVyfemVZeZDRwMUx5VWfwVFZFWxVUVVJHZEZiV1pdTxbWnFZcV2fmU1ZWZEZXnFZWTW1KmFbWWvBOnE52TxU1U1ZFWXtWVEZTUlFSp1RdWy1SM0JUVyjaQ1IjWxtwMwbUUvA1M1UkODFunVb3VybSWGJdWxRVMVaiUxZKpyFGmG1Wm295VyfmV2QkVztVm1ZTYzbGVVbgQwfNVxx5ZUtwTxZdMWfWWEZ3WxUjSWJFOVtWRUalYVZmT1YjUztwRlFXVvJKSxZeUwNSMWjXVGjaWxbFSzVmVEbkWWjSpxZgWy9NREZXWvBSR1YjSxpXmlxXTW1KVFReZFpWnVV6Y0ZCU1bIQwjWRyMjVvFmqFRXSxVum1beVWjaQ1ZenHVTm3RUTVtCMxRWmHpWRwbGY3bGVxbFSxtmVyRTV1ZOpxpdNU5SSEJFVxRGn1YjZEpWm1beUxtSVxZfUxpOVxbXVyjwVWNFNVZVnTsjVwUjSFxeZFpum0bMVXbGYVJdMVpWnFJfVxRWSFZdWzNVMVJIVyjaVWJ6Vw9UVVJ3U0ZVqFVdZG1vRzBXVy5GMFUjWxpvMwZXY0ZmWFZcRw9WVw5VVyjSnWJ6RTFWVEZgTVZNqGIkRy1SVzB1VFo4MVQjm3xxSGReUyfmWVaiVvRWmlFFUy1SVyNURwjmnwJ6WVZmqGNFOVpSVFZQVxRCVxxfnFpTV05VYzbWpVVeWwfvMVbFUWbCoGJ6RxtXm1btVwZJp1penFZvWGtXYVZwU1YjZHZuR1ZTVvJKSVpdVxpwMWRGTVVmnVIlmFFWMFYiUlFwpyJITy9vRTU0Vy01V1VeWxpXnFZXYyfKUFUlQvBSV1ZJV2jKV2J6Vw9XVEJlWxZmp1JeWy9SVzBPVWjwmWMjWwpWnw5VY0ZiR1bUTzpWRwbdY0V0Vw1fSzZVqwZhZDFSqE5YQxpWMyp6VxRCnw5WTzpwRWjfUyjiVxVcQTFRMWR2Vy1WVw1WnGxXm1YiWxZmpw5ESyFSVwbMVGfwT1JeZHtZnTxXV0ZGmFYjZDBWMU5XVWjaVWJdWzNmnTsjVxZmR1b6RzBWnHBXVW05n1UjWXpOWGjVVyjmqxUlRxpXR2RJZEU1nFbFWw1WVEx4VTFGp1VeWy1SWFJeVFo1R1QjVXtuRyRYVye1VxUkOXpunGRGZEZWYVZfmFRVqwZXZDFiSFJeUxpSVzBQVvNGNGRfnFtVm2tQV0tCWFZcQTFURzBGVy1Gn2NVVytmVWRlVyejWGJFNVVWnFZbVyjmT1NGTzxTnVZfU0VKTVpeWxpNRw52TUpGUFpFWzZVnTsjV1ZVqFZdZFVSMUbXWvBSQ1ZdMVtVmlFWTVZKRFZIRw9xVxbZY0ZSV2NIUTFWnTxgTxpVqFNeWy9SMFb1VWjaQ1RGUXtuRXRTVxRGV1RWmGFVMxbWYlJKVyJdNVRWnGRKWVpwRyJGUw5WMUbbVybJqFQkWzpWnxbXY1taUVZcRyFOnGf4YUU5VVJdNVxWnwJTYxpmpw5VpFZWnHBQVWbGT2QjUzZxRlxTVvFKUxpeWzNTMU5YVWjmnxJYUw9WmwbTVxZem1JdOU5WnxJHVyjap1YiMHpXm3tWTVp4V2FYQy9wnVbGTVojTw1VoFtWm1bXWVUjR2RFnG1SV0bVVWbGYVpWWxZWV0bXUyjKSxVXNUfWMUbIWWejYVJWoFBmnTt4ZGjiSGRGTxpvV3tMVxRGVxxfmFpUnFbgUy14VVbfOHtORyR1Uy5OoFZdMWxWSEJlVxZmp1NXSxpuMztMVyjVqFpGUztSnGRXVyjiRFZURy9TMVJ3VG5mTxZYUxVWnVJ3UlFwWE5YZFRSMUbJVTFSR1pdMUtuSE5WVy1amFUiVXtXRxJ2Y0ZOV01VoFZWVyQ0ZDJWp2MkRzBTSEJXWxpSR2VGVXtXm3BiUye1MxbdZHNVMVbZUW14WFZeWvNWRVbPZG1mRVJemFRSnFwiV2fmnw1WTwpuMwZfUxtapxVgQyFSMWjYZUtwV2NGVyfmMFJLWxZOSGJETxZvR2tMVGjmS2VWVzZZnE5XTTFKS1YlQyFUMDVXVWjwVWJ6VxtVnGtDZGjRqFZdZFNvRlxcVwo1V1UiMUtZVEZXYvJ4UFZUQXtTVwZ2Y0ZiTw1fSxBWVEZTVDA1V2IkRy1SWEJWVyjaQxwjWzZuRyReVyfiWVZHNUpmVwbYWWf0WGJdoEjVM0J3VvFdqyRGmGjNnUbPV1RCV1bXWwpVnGtXYvFiYVbeZFNUVxbHYUU5T1ZdoDVWM0YiVwZmWGJFZFtuMValWyfmn2VGTztOVyRXVwVmS1pdWyFVMyj3Vy5WU2NfmHVUVxUjUvFWm1FgZHBSnFajVVo5p2JeWzZOWGtWY0ZKSFRWWxNTVw53VW05V01EVzNWRxbtYy1eV1RemFpvRwb3WxROo1NeUxpWnUZUTVo5m1bdY3tVMVbZVVRGV1JWVyxmWEJPVxZGpw1VNVpWnG94VxRGn1YjRzpUnyRgUxtCnFbXOTBTnGR3VxRWnxZdNVZVnTsjVyeiqFpeVxZvR3tMVW5CpxwjoExVnTVfUxRWUFpUSTFmVxbHV1pOT1pIQxpUVVZtVEZWp2FFOW1vRzBHWyfwmVZfWxVvR3tXVwViUFV6Rw9WnWRHYwZSTxNFSxpXVlVDTwZSp2RFVyFNMztVVWfWYWRWnHpWnUZeVvBWmxZgRwpWRxbYWVRGVw1XmFBVnwJtU1ZSqGRGVxpmRxZbVyjmVw5WTxptSGRVY0p4VVRVUwpTnFV3WzbWVGJ6RxpUVytPVwZJp05HSxZWnXtUWxRKS05eZHZwRzBXY0tRqVZYRXtVMDVIU25mU2IlUzZWMFYiUvFSVxZXSxVSmlVZVy5Co1ZeTwpSmxJtUyjmmGFWWxpWnFb4TVZanVZUVxbWnwJXWVpWWFZeWxRuM1JYVWjSR1pGVzZtRTxPVyjKWxZYQxNmV2j3ZEVeVw1GVyxmnFbPVy1mR1VfMWjNMEaiVwtCV1xVMUpUnGRtUy1aVVZeZFNWVyjYTxZmoFJeSxtWnTxhV21mqFxdpGFSVzBYVxVwT2RdMVtvRxZXUxViSxZeUwNvMytXVG5aVyIlUxRmVEbbZEZwqWRFOVRvRzBYVwo1YVZGWwZwRXRYVvNaM1V6RwfWnWtGZEo1V1ZHOHxWVEZtUvFmR1ReWy9NMztTVvBWS1NGZHZVnGRTTWjKR1aiWzNWVwbYWWejV1ZFNWtVmwF4VyjKp1ZeUxNNRFZQVxpST1QknEpuMwZhUxp4VVZeUwNNMVV5TVU5nFYioDVVM0JLVxUjSVFdZFtWqwZQVG5CU1ZWRzZXnEbeTW5zMVZdWxpvMUbXY0ZmV2NgQxVWmwEjUlFiV2JFpFRWnEbZVvI1R1bWSxtZnFbWYvJaUFReWwfwMxx6Y0ojTyIjoEjWRxblVy1zqFNeVxNuqwZ1VWjmYWRWoEpWnUZOUyjiV1QjVy9WVxx4UxRGWw1gmGtWm1bTV0peRxpfVxNWMwbKVxtCn1QkWzZOVVbtUxtSVFZfOUfURxbVUy05n1YjSxtWVlxtVxZmqVFeVxtum1bIVTNCp1YjoEpWnTxXTURSmVpXOVpwMxZ3VWjaVyIlUxpmV1JDTxZVqFZgoE5WnHBHVFZWNGIjSyfvRXBYY0ZWmVVURw9XRxZ5V2jOTxJFWwbWVxbtUTFJp01WWw5XRzBZWxRKU1IjVXtXnUZUVxRGWxbdVzNXmlFIWW1KVw1fSxBUVxbtV1ZSp1VeVxpWRVZaVxo1R1NfZ3tUnGtUYzbWpFbgQvBWRxJXVybCU2NHOWfWnwY0VTJmRyRGnFpuMValWxZwU1JWSzZXmlVeTW1KTxZYRXtTMDFXU1pSVyNGWzpWnGtlVDFwVVFeZFpSnEbHWyfVMWJWWxtZm3tXYyfKmFpWWzpxRzBHYUZWV1YkpGxWnTxXYvJWp1pgnFJvnxJXVyjSp1RGnGfTm3RYUy05mFbVmHNWMDFHZEVwWFYlUwtVqwbOWWjWVVJeTy1TRUbWVvI1Q05GTzpwRVZXY0ZmVVZdVwZZnFb2Vy1GnVIjWxxXm1ZtVGjKVVJcVxZNV2tYVxVVqFIkZEpVnFZUUxVemxZfOVpwMxZ3U2jWUyNUVxtmVEbbVFZmRVNfRxRvSFJHVFZmV1ZHWxZXm05WTW1KmFUlQvBOnE55Y0ZmV2J6VvRXm2RbVDFwSFNgWy5SM0JQVyjaQxxWVXxZm3RhVye1WVZgQwNmVxb5UWf4V1JXqERVmwZ2WwZmpyJHOVNNSFI1VxZSQ2RfZ3tVnFZSY25SV1RVUwpNMXBHV2f0TxZdNUpWnwYiVvJepyRFpFVWRVbQVyjwT05eSzpuRlFOUvJ4qxZdUwNZVwb2TVtwYVJWSxVWnwJtVVZdqWVIZFRvRwbXWxVWn1pdMHtXm3tXUyjiTFZcQXtSnVbIZUU5V2NFoE1WMvxhVDFNqFRgmFpuqxZVVFRGS1ZenHVTmwJUVy5CV1VgSwpuMUbGV1pKVxbFSTBmVEZPVyejVyRGTw5SMwbYVxRJqFMjUztSnxbmTTJ4VxVfUxpURyRVVG5wVE1eSwptRVJXY0ZmWFVdMVpSRUbaVFtCYVNGUzpWnE5OY0VZMFZYRTFUnWj3U2jaU2IlmFRUVVJ3TxZiRxVdZFVWMGjaVvNGmWIjWXtXm2RYVwVmpxV6Sw9wnVbdVy01nE1fSxZWMvVHVTFNqGRFVy1SV0bUVybCpxxeUxVRnxbiY0ZWmxReVzpUnVZdUyjaVyIkmFBmnwJPZVZWp1ZgQxNSVXBQVxo1R2IjRXtUnFZTY1RWV1RUQvBWVzBHYUZOU2J6RvNXm1ZlVwpVqU9ERxZNnyoiVXbGT1YjVzZwR1ZXVvJKSxpdVxpvMVJ3VGfmnVIkSxZUVyRlVDFmVVFcUy9NVwbJVTFSV1ZFMUpXnxJYY25STFZHOHtSmlFYTVZSnVZYQTBXVEJXYlJmR1VeWy5TSFJtWyfVME1eWwpVm2RVY1U1NVZemHNWmlF1Y0VwWGIkYlFmWEJhZDFSqGNHMWjNnyokVyfST1MjUzpUnFbeU0paVVVcQTBZnFZdVGjOnFZUVxpmm1UjV2eiqVxdmFZvnxJIVW5CT2RfWwtxRxbOUvJKTFYjUwfunWjXVGjWVWNFSyjmnTsjUlFmRxb6RxRvSEJXVy05NFZGWwZOREZmY0ZWmVUlRxNWMxZFU2jmTxIkSXtWVEx4VDJmp2RFWxpXSEJ0VFtKQ1MjZHpWVFZiVyjKV1aiUxpWR1V4V25wV1JeWxBVMvt4ZUU5WVNeUxNNVVV4VwZWV1xWTztVnFbgU0tCV1ZeWyFTnFx5ZUtwnWJ6VwpXmw4iVvAjRyREWxtWRVb2YUtCU1NGUztwRxZXVvNzMxpeWzNwMU53Vy5mTxZUVxZVnGRaWWjepVFeZGjvRVbZVxo5YVUiMUtZVEbWTVpaTFRWZFpwnVV6YwZWVFJVoExWMWN4VDFKqFVdmFRvR3tVVFVwU1MjoEpWm2RVVy05m1ZfOTRunVbGTwpKVyJdSxtmVEbXVxZOpyVGoG1vRzBXV1pSQ2QjZEpUm1bfUvNSVVZemEJZVxZ1UVRGn2NFNUZVMVJTYxUjR1ZcUyFSnXtEVTBmpxxVMVtwRytfVxRWWxZXUwNwMVbHVWjmnxJFWw9Vm1btVyjVqGFGZE9Wm1akWvBmV2NGWxxVm3BYY0ZVMWFGWy9wVwb2TVo1U1pHqDFWVxbWWWjOp2NImGFSnFbUVFo4MVQjVztxSFbiUyjKWFZHOTRmVwbdY0RWVyNHmFBmnwJ2WwZOp1ReVxpWnw5bVwZmV1YkmEpSnFbfUwZmVFbUTwNWRxb1Uy5OVGNIQxtWRlxhVTFKRyRFpFbvRxbIVTNGV1ZfVwVRnGRUUvJKS1ZdWy9WMVZHYUVmnFJeSxZWnVJ3YwZVqFZdZFVSmlVZVy5CQ1RdMUtxRFbXYyfinFUjVXtWMXBJV2jSU01VoEtWV1JPVG1eR2MkTxVuqxZtWxpSR05WoEtZmlxUY1ViR1ZgRvBuMVx4U2f4V2IkYlBtVxbPZG1mRxpemFNWnwEiVyfmnw5WTwpvSGtVYvJapxVgQwbNVxZdUW5OnGNFNVZVWEZHVyejRVJdMWFSnHBMVFZmU1ZfVXbuRyROVyfiSxZURxZZnVbXVG5wVyJ6VxVVnGRbZFZWp1ZXSzBuqwZXVFZSV1ZGWwZXmlxmTW5amFZeWzZZnFZ5Y0ZwV1ZIQw1Xm1ZtVDJmp1pgWy1SMztYVFROQ1MjUxpWnyRhY0ViNFUkNVpWRyRHU25SVWNHqEjWSEJPZFpVqyFGVxpuqxZIV1o1Q05HVXtWV0ZYYvNSYVbYQxpOVxV5TVV0VWNVWvJXmw5hVGjmWFxXRxVWMwbQVwVmT1YjTztNVTVTVvJKqxZeUwJZnFJWTVZmU2NfmFRUWEJGWWjWqFxgoG9NVyjaWvBWMFbWSwtZm3tXUyjmM1RWWyFTVxb3VW5CV01WoHNWRyN3TxZSV1RdmFpvRUbPVWjSR1ZWZFVRnyRUTVtCMVbdZDBWRxbGU2f0WFYlmHbWRVbWWTJwRyRFNWjNnUx3V2fWYVIjSzpUV0ZfUvNSnFRVWvBOVxV4VxpKVE1eSxxWRlVHYxZmVxpdpGFSnWtUVWbGV2QjoEZXnFJXTVZiVxpeYlFVnWjHYvJGnxJYmFVmm2RTUlFiRxpeZFZSm3AkVFZwp1ZGSwZXm3RWTVZmM2FIQxNTRxZ3VWjKV1YkSvFWMVJLUvFSpw1YWxpuM2tVWyfVMVpWnHpuRw5WY0ViV1aiZEpmVyRIWWbCVw1XmFNUm2RKWwZmpyVGUxpuM1JLVvFST1YkVztUmxbTY1RWT1bUSyxUVxbVVG1GVFJURvVWnTw0VwpmV1pXSxbNnytYVTBmT1ZfmEZOVw5OUxZiU1ZUQy9UMVJ4U2fmWGNXqFRWnGtCWVZVqFpdOWjSmlVZVy5Co1VfVXxZm3tXUyjiWGFYQxZZVxb2Txo5U2J6VxbWRxJDZDJWV1VemE5WVEZVVyjSR01GoEtZmlxOVye1NVZYQyFVMVb3ZEV4Vw1WWvNVqwbPTyjKpw5XMVpvm0bMVyfmV1MjTzpWnxbOV0tCVxZcQTFSMVbWVyfwV1JeSxxUnGt3Vy1WqFxdnFZvR2tUVGjVMVZfVXbwRxZOY0tRMxZURyFuMytIVWjwVGNYUxVmnwJLVFZWp1peZHBWnHBYVwo5YVZWSXpOR0bmTUZmWFbYQxbZMVZ2ZUZmTxYjSwfWVEa0ZDFKp1JgWxZvWEJPVy5CS1RGZFtOWGRfY0ViWVZXNVpWRxbYVWf0V1JfY3tXVxV4VyjmpyVHNU5Wm1V4VvFSQ1ZfZ3tVnFZUYvJ4YVRURyFZnFV4Vy5wVWNGVytWM0Z3YxUjRVJdpFVWMwb2WxtGT2QjTzZvRTxXV0VKTFZdWy5NVw5HZEVWU2IlmHZVmwIiV1ZmpVFgZG1SnFa0VDFWS1YjSxtuREbmTW1KTFRWWwbmRxZ3VW1WTxNGSxBWV1JCTwpzqFRgZFVvWFJVVWjmYWReWxVRmwJTY0o5mxpdVvBWRwx4UxRGWw1cVxRWm1bTU0U1VVJeWxpuqxZQV1ROMFIkWzpTV0ZfUvJ4VxbeUzpSMVV4VxpKn1YjSxtWRlVXV2ejWVFdoFtum0bUVTNCpxxWWzpWnFZXVvJKWVpXNU9TMVbHYvJSVGIjoGjVnVJ3WTFVqGFFOU9WnFbKVwtCU2IjWxxVnXtWYyfKWFV6Ry9wMUb2ZEU1TxJFSXbWVEZlUlFOpw1YWw5WWEJUVybBME1WVXxOVw5UTVZem1bdVvBmVxbVY0V4YVIkSxRmWEJtV1Zwp1VfOVpWVy8kV1RGV2QjWzpUnxbtUyfKpVbUSy9ORxbGWzbGWxZdNUbmm1YiYvFKWVFcSxZmRUb2VTFmU1ZWRzZxRxbOY1ZKVxZUSXtVmlVXZEZwnxIlQxBWnwIiU2jwp1ZUVxJNVTVWVW01R1ZdMUpwSE5WY0ZmmGFYQzpxRw55V2jSU1YjSxZWnTVDTwpWqFVeWzBTSFJXVFRKmWReoEZXmlxfY1VmMxaiVyxWnVbVY0ViVVZeVyxVqwbTUvFmqGRHVxpWnxJVVwtCV05GTxpwRyRtUyfmVFbUSyxTnGf3VybSnE1EnFpmMFYiV2ejqFRcWxpSnEbEVwtGT2RfWwtwRxZXTUtSTFYjYlFwMVJ4VGbmU2IlUzpmnTwiVwZiR1ZdpFNvRTVXVFZaV2JfWwZOVWRWY1taM1ZFWwfXVwb2ZEZiV2J6VwxWVlxhVTA1SFRdWy1SM1J3VyjaQxxWZFtwRyRVVyjKWVUkNUpVMxb3V2jWWFZFm3ttWEJXZGjKpyVGTxpNRFYjV2jwNGQjTXpPVytYYvNaYVRVUwpNVzBHV2e5T1ZdNVbWVlw0VvAjSVVdpFtWnHB2VvFmS1ZWSzZTnTFfYzbWVxZURxpZVTFHVxpOYVNFWxVmVEbTV1ZiWGQkSxRNnEbZVGjSQ1ZeWxVSm3RmWwU1SFUlQw5ZVTFYY0ZSWFJWoE9WRxbWWW1ap1VdmFZWRxbUVFZaQ1MjWwpVnE'
enc_ciphers = ['rot13', 'b64e', 'caesar']
dec_ciphers = ['rot13', 'b64d', 'caesard']
def rot13(s):
_rot13 = string.maketrans(
"zyxwvutsrqponZYXWVUTSRQPONmlkjihgfedcbaMLKJIHGFEDCBA",
"mlkjihgfedcbaMLKJIHGFEDCBAzyxwvutsrqponZYXWVUTSRQPON")
return string.translate(s, _rot13)
def b64e(s):
return b64encode(s)
def b64d(s):
return b64decode(s)
def caesar(plaintext, shift=4):
alphabet = string.ascii_lowercase
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
table = string.maketrans(alphabet, shifted_alphabet)
return plaintext.translate(table)
def caesard(plaintext, shift=-4):
alphabet = string.ascii_lowercase
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
table = string.maketrans(alphabet, shifted_alphabet)
return plaintext.translate(table)
def encode(pt, cnt=50):
tmp = '2{}'.format(b64encode(pt)) #2.format(b64encode(pt))
for cnt in xrange(cnt):
c = random.choice(enc_ciphers) # choose some enc_cipher
i = enc_ciphers.index(c) + 1 # position in the array + 1
_tmp = globals()[c](tmp)
tmp = '{}{}'.format(i, _tmp)
return tmp
def decode(tmp, cnt=50):
for cnt in xrange(cnt):
i = int(tmp[:1])-1
_tmp = tmp[1:]
c = dec_ciphers[i]
tmp = globals()[c](_tmp)
try:
s = b64decode(tmp[1:])
if s.find("flag") != -1:
return s
except:
pass
return b64decode(tmp[1:])
if __name__ == '__main__':
cnt=70
print "Cnt: %d" % cnt
print decode(FLAG, cnt)
Here is the error message:
/usr/bin/python -u "/media/pc/A8560F93560F6204/Python investigation/transfer_csaw2015 fully MODDED2.py"
Cnt: 70
Traceback (most recent call last):
File "/media/pc/A8560F93560F6204/Python investigation/transfer_csaw2015 fully MODDED2.py", line 64, in <module>
print decode(FLAG, cnt)
File "/media/pc/A8560F93560F6204/Python investigation/transfer_csaw2015 fully MODDED2.py", line 47, in decode
i = int(tmp[:1])-1
ValueError: invalid literal for int() with base 10: 'W'
I read from a hex file that's 1444352kB of size. I take 128 bytes of data and try to pack them using python struct.pack.
Below is the code :
#!/usr/bin/env python
import os
import struct
import ctypes
import array
import binascii
import sys,getopt
filename = file_location
blocksize = 1444352
opts,args = getopt.getopt(sys.argv[1:],'f:b:')
for o,a in opts:
if o == '-f':
filename = a
if o == '-b':
blocksize = a
offset = 0
with open(filename,"rb") as f:
block = f.read(blocksize)
str = ""
for ch in block:
str += hex(ord(ch))+" "
sector = []
c = 0
for s in str.split(' ') :
sector.append(s)
c += 1
if c == 128 :
sector.append("")
c = 0
#print sector
sector = ', '.join(sector)
#print sector
print type(sector)
sector = sector.split(',')
secdata = []
for items in sector[0:127] :
secdata.append(items)
secdata2 = ','.join(secdata)
print secdata2
print type(secdata2)
struct.pack('B', secdata2)
break
The secdata that appears to be a list, I have converted to string. but I always get error struct.error: cannot convert argument to integer when I try to pack the 128 bytes of data.