having a brain fart. But how do i decode a string that contains.
t = '%2Fdata%2F'
print(t.decode('utf8'))
'str' object has no attribute 'decode'
expecting /data/
2F is a hexadecimal number of / character. Python has chr function that returns a character representation by a decimal number.
So you need to get two symbols after %s and "decode" ("hex" -> chr(int("hex",16))) them into a character.
def decode_utf(string):
for i in range(string.count("%")):
tmp_index = string.index("%")
hex_chr = string[tmp_index:tmp_index + 3]
#replace only one characher at a time
string = string.replace(hex_chr, chr(int(hex_chr[1:],16)),1)
return string
print(decode_utf("%2Fdata%2F"))
#/data/
print(decode_utf("hello%20world%21"))
#hello world!
Edit 1:
The previous code breaks if there's %25 character, use the code below.
def decode_utf(string):
utf_characters = []
tmp_index = 0
for i in range(string.count("%")):
tmp_index = string.index("%",tmp_index)
hex_chr = string[tmp_index:tmp_index + 3]
if not hex_chr in utf_characters:
utf_characters.append(hex_chr)
tmp_index += 1
for hex_chr in utf_characters:
string = string.replace(hex_chr, chr(int(hex_chr[1:],16)))
return string
print(decode_utf("%25t%20e%21s%2ft%25"))
#%t e!s/t%
Related
in attempt to make simple code to convert a hex string to base64:
my thought was: hex -> integer -> binary -> base64
so i wrote this little code:
import string
def bit(integer):
# To binary
return int(bin(integer))[2:]
#Hex multiply by 16 depending on position: 0xAB = A*(16**2) + B(16**1) = #10*16**2 + 11*16**1
#0x3a2f
#3*(16**2) + 7*(16**1) + 5
def removeletter(list):
#"abcdef" = "10 11 12 13 14 15"
for i, letter in enumerate(list):
if letter in hextable.keys():
list[i] = hextable[letter]
return list
def todecimal(h):
power = 0
l = [num for num in str(h)] #['3', 'a', '2', 'f']
l = removeletter(l)
l.reverse() #['f', '2', 'a', '3']
for i, n in enumerate(l):
number = int(n)
l[i] = number*(16**power)
power += 1
l.reverse()
return sum(l)
lowers = string.ascii_lowercase
hextable = {}
for number, letter in enumerate(lowers[:6]):
hextable[letter] = number + 10
in this little challenge i am doing, it says:
The string:
49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d
Should produce:
SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t
ok,
print(bit(todecimal('49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d')))
this should get the binary of the hex string, which if I put through a binary to base64 converter, should return SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t. or so i thought.
└─$ python3 hextobase64.py
10010010010011101101101001000000110101101101001011011000110110001101001011011100110011100100000011110010110111101110101011100100010000001100010011100100110000101101001011011100010000001101100011010010110101101100101001000000110000100100000011100000110111101101001011100110110111101101110011011110111010101110011001000000110110101110101011100110110100001110010011011110110111101101101
after checking using a hex to binary converter, i can see that the binary is correct.
now, if if i put this through a binary to base64 converter, it should return SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t, right?
the thing is, this binary to base64 converter gave me kk7aQNbS2NjS3M5A8t7q5EDE5MLS3EDY0tbKQMJA4N7S5t7c3urmQNrq5tDk3t7a which is odd to me. so I must be doing something wrong. from my understanding, hexadecimal can be represented in binary, and so can base64. base64 takes the binary and groups the binary by 6 digits to produce its own representation. so obviously if I have the binary, it should be interchangeable, but something is wrong.
what am i doing wrong?
I need to remove all the numbers from the string recursively and then return the reversed string.
def remove_numbers_and_reverse(string):
if string == "":
return string
elif string[-1].isdigit():
string.replace(string[-1], "")
return string[-1] + remove_numbers_and_reverse(string[:-1])
For example if the input is "bunny1234" then the output should be "ynnub". But i get "4321ynnub".
"bunny1234" -> "ynnub"
"3434string" -> "gnirts"
For Removing number try below approach:
1. using join and isdigit
ini_string = "Test123ing127you"
print("initial string : ", ini_string)
res = ''.join([i for i in ini_string if not i.isdigit()])
print("final string : ", res)
2. Using translate and digits
from string import digits
ini_string = "Test123ing127you"
remove_digits = str.maketrans('', '', digits)
res = ini_string.translate(remove_digits)
# printing result
print("final string : ", res)
3. Using filter and lambda
ini_string = "amol23bais"
res = "".join(filter(lambda x: not x.isdigit(), ini_string))
# printing result
print("final string : ", str(res))
The problem with your solution is the elifpart: You are not doing anything with your replaced string, replace is not working in-place. So instead you might try this:
def remove_numbers_and_reverse(string):
if string == "":
return string
elif string[-1].isdigit():
return remove_numbers_and_reverse(string[:-1])
else:
return string[-1] + remove_numbers_and_reverse(string[:-1])
print(remove_numbers_and_reverse("bunny1234"))
print(remove_numbers_and_reverse("3434string"))
Here I just ignore the last character if it is a digit.
For shorter and smarter solutions see #Amolb's answer.
Other people have answered it but might as well throw in my example too.
def remove_numbers_and_reverse(my_string):
if not my_string:
return my_string
else:
for letter in my_string:
if letter.isdigit():
continue
output = letter + output
return output
The output:
[user#machine test-dir]$ python3
Python 3.6.9 (default, Aug 15 2019, 16:59:35)
>>> import test
>>> test.remove_numbers_and_reverse("bunny1234")
'ynnub'
>>> test.remove_numbers_and_reverse("3434string")
'gnirts'
>>> test.remove_numbers_and_reverse("3434string123123morestring")
'gnirtseromgnirts'
>>> test.remove_numbers_and_reverse("")
''
>>>
So basically my homework consists of making a program that asks for a string and an integer 'x'.'x' is basically the step in this program. First it converts the whole string to lowercase and then each 'x'th' character of the string must be converted to uppercase. So if i input "Hello World" and my integer is 1. Output would be "hElLo wOrLd". Im new to python by the way.
This is what ive got right now and im basically stuck in a loop of trying a 100 things:
s = input('Input a string: ')
g = input('Input an integer: ')
s = s.lower() #converts the whole string ofc
s = list(s)
range1 = s[::g]
range1 = range1.upper()
print(s)
First, convert g to an int because input returns a str and you can't slice a list with a str, also, s[::g] (which should be s[g::g + 1]) is an independent sublist of s, and it has no reference to s, so assigning it to range1 and modifying it will not modify s, and one more note, s[::g] is a list, and you should call str.upper on its elements, not on it itself, you can use map for this:
s = list(input('Input a string: ').lower())
g = int(input('Input an integer: '))
s[g::g + 1] = map(str.upper, s[g::g + 1])
s = ''.join(s)
print(s)
Input:
Input a string: Hello World
Input an integer: 1
Output:
hElLo wOrLd
How to create a whole list of string from one string where each string in the list containing exactly one character replacement? The string itself is consisted of only four characters (say: A, B, C, and D), so that the whole list of a string of length n would contain 3n+1 strings with exactly one character replacement.
Example:
inputstr = 'ABCD'
output = ['ABCD', 'BBCD', 'CBCD', 'DBCD', 'AACD', 'ACCD', 'ADCD', 'ABAD', 'ABBD', 'ABDD', 'ABCA', 'ABCB', 'ABCC']
I write the following python code:
strin = 'ABCD'
strout = set()
tempstr1 = ''
tempstr2 = ''
tempstr3 = ''
tempstr4 = ''
for base in range(len(strin)):
if strin[base] == 'A': #this block will be repeated for char B, C and D
tempstr1 = strin.replace(strin[base], 'A')
strout.add(tempstr1)
tempstr1 = ''
tempstr2 = strin.replace(strin[base], 'B')
strout.add(tempstr2)
tempstr2 = ''
tempstr3 = strin.replace(strin[base], 'C')
strout.add(tempseq3)
tempstr3 = ''
tempstr4 = strin.replace(strin[base], 'D')
strout.add(tempseq4)
tempstr4 = ''
return strout
and it works well as long as there is no repeated character (such as 'ABCD'). However, when the input string contains repeated character (such as 'AACD'), it will return less than 3n+1 string. I tried with 'AACD' string and it returns only 10 instead of 13 strings.
Anyone can help?
change
strout = set() ===> strout = list()
I found it. I used a slicing method to create a list of total combination of strings with one replacement.
for i in range(len(seq)):
seqxlist.append(seq[:i] + 'x' + seq[i+1:])
and after that I filter out all the x-replaced strings which are longer than the original string length:
seqxlist = [x for x in seqxlist if (len(x) == len(seq))]
Then, I changed x into any of the substitution characters:
for m in seqxlist:
tempseq1 = m.replace('x', 'A')
outseq.append(tempseq1)
tempseq2 = m.replace('x', 'B')
outseq.append(tempseq2)
tempseq3 = m.replace('x', 'C')
outseq.append(tempseq3)
tempseq4 = m.replace('x', 'D')
outseq.append(tempseq4)
This will create all the possible combinations of string replacement, but still contains duplicates. To remove duplicates, I use set() to the outseq list.
I tried to convert int into hex and concatenate the hex into a string and write it to files.
but when i do the following:
c = ""
c = hex(a) + hex(b)
i got error saying
'str' object cannot be interpreted as an integer.
How to solve this in python3.5?
Solved:
it turns out a is a string and i want to strip off the leading 0x so a better way that transforms this to plain hex is to do {0:02x}.format(yourHex).
a and b should be integer because hex takes integer and it returns string so you can concatenate the output of those two hex().
a = 5
b = 7
c = ""
filePath = "C:\\..\\..\\hexFile.txt" #Path of your file
with open(filePath, "w") as file:
c = hex(a) + hex(b)
file.writelines(c)