Base64 URL encoding fail - python

I have a little program here which try to generate a specific hash value for a website (Path of Exile Passive Tree).
Here is my code:
####### ByteEncoder.py (This is a python convert from the official js code )
class ByteEncoder:
def __init__(self):
self.dataString = ""
def intToBytes(self, t, n=4):
t = int(t)
i = [None] * n
s = n - 1
while True:
i[s] = 255 & t
t = t>>8
s -= 1
if s < 0:
break
return i
def appendInt(self, t, n):
i = self.intToBytes(t,n)
for r in range(0, n):
self.dataString += chr(i[r])
def appendInt8(self, t):
self.appendInt(t, 1)
def appendInt16(self, t):
self.appendInt(t, 2)
def getDataString(self):
return self.dataString
##### main.py
hashes = [465, 45035]
encoder = ByteEncoder()
encoder.appendInt(4,4) # Tree Version
encoder.appendInt8(2) # Class ID
encoder.appendInt8(0) # Ascendency class
encoder.appendInt8(1) # Fullscreen
for h in hashes:
encoder.appendInt16(h)
d = str(base64.b64encode(bytes(encoder.getDataString(),encoding='utf8')))
d = d.replace("+", "-").replace("/", "_")
print(d)
I get the Hash AAAABAIAAQHDkcKvw6s= but i should get AAAABAIAAQHRr-s=
Can someone tell me why?
If you wanna test this
What i want:
https://www.pathofexile.com/fullscreen-passive-skill-tree/3.6.6/AAAABAIAAQHRr-s=
What i get:
https://www.pathofexile.com/fullscreen-passive-skill-tree/3.6.6/AAAABAIAAQHDkcKvw6s=
Here is the Anwser from the comment of Victor.
Simply use base64.urlsafe_b64encode()

You are treating your text string as if it where bytes, and then encoding it with utf-8, which is a multi-byte encoding.
If you need a "transparent" text-to-bytes encoding, use "latin-1".
However, in this code, you should not have been using a text-string ("str") to startwith. It will also simplify things in that you can concatenate the integers directly into your data, instead of converting byte by byte:
...
class ByteEncoder:
def __init__(self):
self.data = bytes()
...
def appendInt(self, t, n):
i = self.intToBytes(t,n)
self.data += i
...
# Also,in Python, there is no sense in writting a "getter" to
# just return an attribute as it is - no need for an equivalent
# of your `.getDataString` method:
d = str(base64.b64encode(encoder.data))

Related

Encrypting a Text File in Python, Preferably with a Module [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Context:
I have a class, in which I have to make a password protected something or other.
(My instructor is not very specific.) The reason for me asking for a method in which I could use a standard import statement was so I could just upload a single folder that only contained a text file and the program itself. I want to do something as follows:
#Import Statements Here
outFile = open('myFile.txt',"wt");
#Here is the tricky part.
#In place of all of these comments,
#I want to encrypt the file with a key given by a user(in this case,givenKey):
givenKey = input("Please input your key:>>>");
outFile.close();
Resolution:
The answer by Sasszem was the one that worked for me. Look into the comments
for a simplified explanation of the main answer. The person who gave me his/her custom made code (I cant remember who gave it to me, sorry.) had a good idea. But I don't like using code I don't understand. And finally, the person who gave me the Cryptography module as an idea wasn't wrong, but I use python on Windows.
A simple way to encrypt data is to add a constant to every byte.
You can generate some random byte from the pwd and then add it to every byte in the input. It won't be strong, but it's simple.
If you make something like your program generates random numbers to add to the bytes after seeding your pwd to the random generator, your instructor will be impressed.
To decode, simply subtract the same numbers from the bytes.
Package cryptography provides support for encryption/decryption: https://pypi.python.org/pypi/cryptography. I understand that it is included in Anaconda.
Here is a module I wrote a while back. It uses only built-in python modules. I give you permission to use it!
import string, random
class Round(object):
def __init__(self, *seqs):
self.position = 0
self.data = [i for x in seqs for i in x]
self.len = len(self.data)
def __repr__(self):
return str(self.data)
def __iter__(self):
self.position = 0
return self
def is_item(self, item):
if str(self.data[self.position]) == str(item):
return True
return False
def __getitem__(self, index):
if index < self.len-1 and index >= 0:
return self.data[index]
else:
while index < 0:
index += self.len-1
while index > self.len-1:
index -= self.len-1
return self.data[index]
def next(self):
if self.position >= self.len-1:
self.position = 0
raise StopIteration
else:
self.position += 1
return self.data[self.position-1]
class JCripter(object):
def __init__(self, string):
self.string = string
self.generate_key_set()
self.encrypted = False
def generate_key_set(self):
self.alphabet = list(string.ascii_lowercase)
self.numbers = [str(x) for x in range(10)]
self.special_characters = ['"',"'",',','?','.',
' ','(',')',':',';',
'!','#','#','$','%',
'^','&','*','_','-',
'+','=','<','>','~',
'`','{','[','}',']',
'\\','|']
self.key_base = Round(self.alphabet, self.numbers, self.special_characters)
def get_key_index(self, key):
for i in self.key_base:
if isinstance(key, int):
if i == self.key_base[key]:
return self.key_base.position-1
elif i == key.lower():
return self.key_base.position-1
else:
print 'not found'
def __repr__(self):
return self.string
def _encrypt(self, string, func, *args):
if string == None:
string = self.string
if string == None:
return
string = string.lower()
n_string = func(string, *args)
self.encrypted = not self.encrypted
self.string = n_string
return n_string
class CeaserCypher(JCripter):
def __init__(self, string, shift=None):
JCripter.__init__(self, string)
if shift == None:
self.shift = random.randint(0, self.key_base.len)
else:
self.shift = shift
def encrypt(self, string=None):
def inner(string):
n_string=''
for i in string:
if self.encrypted == True:
n_string += self.key_base[self.get_key_index(i)-self.shift]
else:
n_string += self.key_base[self.get_key_index(i)+self.shift]
return n_string
return self._encrypt(string, inner)
class PseudoRandomCypher(JCripter):
def __init__(self, string, shifts=None):
if shifts == None:
self.shift = [random.randint(0, 500) for x in string]
else:
self.shift = shifts
JCripter.__init__(self, string)
def encrypt(self, string=None):
def inner(string):
ind = 0
n_string = ''
for i in string:
if ind >= len(self.shift)-1:
ind = 0
if self.encrypted == True:
n_string += self.key_base[self.get_key_index(i)-self.shift[ind]]
else:
n_string += self.key_base[self.get_key_index(i)+self.shift[ind]]
ind += 1
return n_string
return self._encrypt(string, inner)
class PolyAlphabeticCypher(JCripter):
def __init__(self, string, key, enc=False):
JCripter.__init__(self, string)
self.key=list(key)
self.encrypted = enc
def encrypt(self, string=None):
def inner(string):
index = 0
n_string = ''
for i in string:
if index >= len(self.key)-1:
index = 0
if self.encrypted == True:
n_string += self.key_base[self.get_key_index(i)-self.get_key_index(self.key[index])]
else:
n_string += self.key_base[self.get_key_index(i)+self.get_key_index(self.key[index])]
index += 1
return n_string
return self._encrypt(string, inner)
n = 'Hello world my name is anonymous!'
p = PolyAlphabeticCypher(n, 'super_secret_password')
print p.encrypt() #--> returns encrypted data
print p.encrypt() #--> decrypts data
#if you are decrypting a previously encrypted text
n = 'Some sensitive data'
first = PolyAlphabeticCypher(n, 'some pass')
my_data = first.encrypt()
second = PolyAlphabeticCypher(my_data, 'some pass', True)
print second.encrypt()

Python returning instance of class from list

I try to get index of instance of object in a list. And I don't know how to do it without for-loop.
If someone can show me right direction, without for-looping it.
I find that list has instance of it with any()-function but can't get index out of it.
I try to clarify my problem. If any()-fucntion can find that list(self.data) has instance of object. any()-function returns only true/false. Is there function or way to get index of that instance so i can call it.
And code:
class MyClass:
def __init__(self, f):
self.data = []
self.f = open(f, "rb")
self.mod = sys.modules[__name__]
def readFile(self):
f = self.f
try:
self.head = f.read(8)
while True:
length = f.read(4)
if length == b'':
break
c = getattr(self.mod, f.read(4).decode())
if any(isinstance(x, c) for x in self.data):
index = self.data.index(c) #Problem is here
self.data[index].append(f.read(int(length.hex(), 16)))
else:
obj = c(data=f.read(int(length.hex(), 16)))
self.data.append(obj)
f.read(4) #TODO check CRC
finally:
f.close()
enumerate is the way to go here.
...
c = getattr(self.mod, f.read(4).decode())
found = [ (i, x) for (i,x) in enumerate(self.data) if isinstance(x, c) ]
if len(found) > 0:
index, val = found[0]
...
Focusing on getting the instance of the object and its index in the self.data list:
# ...
# This gives you back a class name I assume?
c = getattr(self.mod, f.read(4).decode())
# The following would give you True/False ... which we don't need
# any(isinstance(x, c) for x in self.data)
# Now, this will return _all_ the instances of `c` in data
instances = [x for x in self.data if isinstance(x, c)]
if len(instances):
# Assuming that only 1 instance is there
index = self.data.index(instances[0])
# ??? What do you append here?
self.data[index].append()
else:
obj = c(data=f.read(int(length.hex(), 16)))
self.data.append(obj)
f.read(4) #TODO check CRC

Define a new numerical base in python (new charset)

I would like to know how to define a new numerical base in Python.
For example:
base dimension = 4
Charset = 'u', '$', '6', '}' (from the least important to the most)
I would like to know how to create and handle it, to be able to do simple arithmetic like:
$} + 6u * 6 = $$}
7 + 8 * 2 = 23
I know I could use replace to replace u -> 0, $ -> 1 and so on, and use the int() function. However int() is not defined for base > 36, and I will have to handle these cases.
I know I could make my own function to convert them to base 10, do the math, and convert them back, but I would like to avoid that if possible.
Rather than replace, you can use dictionaries to translate back and forth between the charset and regular ints, something like:
charset = 'u$6}'
b = len(charset) #base
vals = {c:i for i,c in enumerate(charset)}
digits = {vals[c]: c for c in vals} #inverse dictionary
def toInt(s):
return sum(vals[c]*b**i for i,c in enumerate(reversed(s)))
def toNewBase(n):
nums = [] if n > 0 else [0]
while n > 0:
n,r = divmod(n,b)
nums.append(r)
return ''.join(digits[i] for i in reversed(nums))
def add(s,t):
return toNewBase(toInt(s) + toInt(t))
def subtract(s,t):
return toNewBase(toInt(s) - toInt(t))
def multiply(s,t):
return toNewBase(toInt(s) * toInt(t))
def divide(s,t):
return toNewBase(toInt(s) // toInt(t))
typical output:
>>> add('$}',multiply('6u','6'))
'$$}'
def str_base(number, base):
# http://stackoverflow.com/a/24763277/3821804
(d,m) = divmod(number,len(base))
if d > 0:
return str_base(d,base)+base[m]
return base[m]
def charset(chars):
class cls(int):
__slots__ = ()
def __new__(cls, src):
if isinstance(src, str):
return int.__new__(
cls,
''.join(str(chars.index(i)) for i in src),
len(chars)
)
return int.__new__(cls, src)
def __str__(self):
return str_base(self, chars)
def __repr__(self):
return '%s(%r)' % (type(self).__name__, str(self))
cls.__name__ = 'charset(%r)' % chars
return cls
Usage:
test = charset('u$6}')
print(test( test('$}') + test('6u') * test('6') ) ) # => '$$}'
See it working online: http://rextester.com/WYSE48066
At the moment, I'm too tired to explain it.

Most object oriented way of solving this in python?

I've been told to write a simple program that generates coupon codes, which should offer more than two algorithms (any two) and that the algorithm and the number of codes generated should be read from a config file. Also I've been told that the solution would involve using a known design pattern and that I should look for what pattern is.
I've come up with two solutions for this, but I don't think I've found a proper OOP design pattern that fits for the problem, since objects are data with methods that operate over that data, and in this problem there is little data to operate over, it's more a function (functional?) problem to my naive eyes. Here are the two, one is basically executing the proper static method for the algorithm in the config file and the other returns a reference to a function. Both generate the numbers and print them to the screen.
First method:
class CouponGenerator:
SEQUENTIAL_NUMBERS = "sequentialNumbers"
FIBONACCI_NUMBERS = "fibonacciNumbers"
ALPHANUMERIC_SEQUENCE = "alphanumericSequence"
quantity = 0
algorithm = ""
def __init__(self, quantity, algorithm):
self.quantity = quantity
self.algorithm = algorithm
def generateCouponList(self):
numbers = list()
if self.algorithm == self.SEQUENTIAL_NUMBERS:
numbers = CouponGenerator.generateSequentialNumbers(self.quantity)
elif self.algorithm == self.FIBONACCI_NUMBERS:
numbers = CouponGenerator.generateFibonacciSequence(self.quantity)
for number in numbers:
print number
#staticmethod
def getCouponGenerator(configFile):
cfile = open(configFile)
config = cfile.read()
jsonconfig = json.loads(config)
cg = CouponGenerator(jsonconfig['quantity'], jsonconfig['algorithm'])
return cg
#staticmethod
def generateSequentialNumbers(quantity):
numbers = list()
for n in range(1, quantity+1):
zeroes = 6-len(str(n))
numbers.append(zeroes*"0"+str(n))
return numbers
#staticmethod
def generateFibonacciSequence(quantity):
def fib(n):
a, b = 0, 1
for _ in xrange(n):
a, b = b, a + b
return a
numbers = list()
for n in range(1, quantity+1):
number = fib(n)
zeros = 6-len(str(number))
numbers.append(zeros*"0"+str(number))
return numbers
if __name__ == "__main__":
generator = CouponGenerator.getCouponGenerator("config")
generator.generateCouponList()
Second solution:
class CouponGenerator:
#staticmethod
def getCouponGenerator(algorithm):
def generateSequentialNumbers(quantity):
numbers = list()
for n in range(1, quantity+1):
zeroes = 6-len(str(n))
numbers.append(zeroes*"0"+str(n))
return numbers
def generateFibonacciSequence(quantity):
def fib(n):
a, b = 0, 1
for _ in xrange(n):
a, b = b, a + b
return a
numbers = list()
for n in range(1, quantity+1):
number = fib(n)
zeros = 6-len(str(number))
numbers.append(zeros*"0"+str(number))
return numbers
generators = {"sequentialNumbers": generateSequentialNumbers,
"fibonacciNumbers": generateFibonacciSequence}
return generators[algorithm]
class CouponGeneratorApp:
configFile = "config"
def __init__(self):
cfile = open(self.configFile)
config = cfile.read()
self.jsonconfig = json.loads(config)
self.generateCouponCodes()
def generateCouponCodes(self):
generator = CouponGenerator.getCouponGenerator(self.jsonconfig["algorithm"])
numbers = generator(self.jsonconfig["quantity"])
for n in numbers:
print n
if __name__ == "__main__":
app = CouponGeneratorApp()
If you want to make it a little more object oriented I suggest you use some kind of strategy pattern, that means, use a class per generation algorithm (which should have a common interface) and specify that CouponGenrator use an object which implements this interface to do whatever it has to do. This is theory and making interface and everything in your case might be a little to much.
http://en.wikipedia.org/wiki/Strategy_pattern
you could try something like :
class SequentialGenerator(Object):
def implementation():
...
class FibonacciGenerator(Object):
def implementation():
...
class CouponGenerator(Object):
def set_generator(generator):
# set self.generator to either an instance
# of FibonacciGenerator or SequentialGenerator
def generate_coupon_code():
# at some point calls self.generator.implementation()

Python -- TypeError on string format from binary output

I'm getting a getting a TypeError for unbound method (at the bottom). I'm teaching myself Python so this may be some simple mistake. The issue is with outFormat(), which didn't give me problems when I test it by itself but is not working within the class. Here's the class:
class gf2poly:
#binary arithemtic on polynomials
def __init__(self,expr):
self.expr = expr
def id(self):
return [self.expr[i]%2 for i in range(len(self.expr))]
def listToInt(self):
result = gf2poly.id(self)
return int(''.join(map(str,result)))
def prepBinary(a,b):
a = gf2poly.listToInt(a); b = gf2poly.listToInt(b)
bina = int(str(a),2); binb = int(str(b),2)
a = min(bina,binb); b = max(bina,binb);
return a,b
def outFormat(raw):
raw = str(raw); g = []
[g.append(i) for i,c in enumerate(raw) if c == '1']
processed = "x**"+' + x**'.join(map(str, g[::-1]))
#print "processed ",processed
return processed
def divide(a,b): #a,b are lists like (1,0,1,0,0,1,....)
a,b = gf2poly.prepBinary(a,b)
bitsa = "{0:b}".format(a); bitsb = "{0:b}".format(b)
difflen = len(str(bitsb)) - len(str(bitsa))
c = a<<difflen; q=0
while difflen >= 0 and b != 0:
q+=1<<difflen; b = b^c
lendif = abs(len(str(bin(b))) - len(str(bin(c))))
c = c>>lendif; difflen -= lendif
r = "{0:b}".format(b); q = "{0:b}".format(q)
#print "r,q ",type(r),type(q)
return r,q #returns r remainder and q quotient in gf2 division
def remainder(a,b): #separate function for clarity when calling
r = gf2poly.divide(a,b)[0]; r = int(str(r),2)
return "{0:b}".format(r)
def quotient(a,b): #separate function for clarity when calling
q = gf2poly.divide(a,b)[1]; q = int(str(q),2)
return "{0:b}".format(q)
This is how I'm calling it:
testp = gf2poly.quotient(f4,f2)
testr = gf2poly.remainder(f4,f2)
print "quotient: ",testp
print "remainder: ",testr
print "***********************************"
print "types ",type(testp),type(testr),testp,testr
testp = str(testp)
print "outFormat testp: ",gf2poly.outFormat(testp)
#print "outFormat testr: ",gf2poly.outFormat(testr)
This is the error:
TypeError: unbound method outFormat() must be called with gf2poly instance as first argument (got str instance instead)
Where you have this:
def outFormat(raw):
You probably want either this:
def outFormat(self, raw):
Or this:
#staticmethod
def outFormat(raw):
The former if you eventually need access to self in outFormat(), or the latter if you do not (as currently is the case in the posted code).

Categories

Resources