How to XOR two strings in Python - python

H, I'm trying to XOR two strings (which should become hex first) in Python.
I know one way will work:
def xor_two_str(str1, str2):
return hex(int(str1,16) ^ int(str2,16))
But I tried sth like this:
def change_to_be_hex(str):
return hex(int(str,base=16))
def xor_two_str(str1,str2):
a = change_to_be_hex(str1)
b = change_to_be_hex(str2)
return hex(a ^ b)
print xor_two_str("12ef","abcd")
This will return TypeError: ^ shouldn't be used between str, str.
I don't know why.
And also this function won't work:
bcd = change_to_be_hex("12ef")
def increment_hex(hex_n):
return hex_n + 1
result = increment_hex(bcd)
print result
The error message is : TypeError: cannot concatenate 'str' and 'int' objects
I feel this is so strange:(
Thank you!

Hi,
The following function is returning the result of hex() which returns a string.
def change_to_be_hex(s):
return hex(int(s,base=16))
You should use the ^ operator on integers.
def change_to_be_hex(s):
return int(s,base=16)
def xor_two_str(str1,str2):
a = change_to_be_hex(str1)
b = change_to_be_hex(str2)
return hex(a ^ b)
print xor_two_str("12ef","abcd")
I'm not sure though that's the result you're looking for. If you want to XOR two strings, it means you want to XOR each character of one string with the character of the other string. You should then XOR ord() value of each char or str1 with ord() value of each char of str2.
def xor_two_str(a,b):
xored = []
for i in range(max(len(a), len(b))):
xored_value = ord(a[i%len(a)]) ^ ord(b[i%len(b)])
xored.append(hex(xored_value)[2:])
return ''.join(xored)
print xor_two_str("12ef","abcd")
Or in one line :
def xor_two_str(a,b):
return ''.join([hex(ord(a[i%len(a)]) ^ ord(b[i%(len(b))]))[2:] for i in range(max(len(a), len(b)))])
print xor_two_str("12ef","abcd")

hex returns a string, so you're trying to xor two strings.
def change_to_be_hex(s):
return int(s,base=16)
Should fix this.

when you initially return hex, like in change_to_be_hex, you explicitly convert it to int. you need to do that throughout your code to add something to it - so, change increment_hex to:
return (int(hex_n) + 1)

Related

Sum the Even Values of a String

In this Exercise, you will sum the value of a string. Complete the recursive function
def sumString(st):
This function accepts a string as a parameter and sums the ASCII value for each character whose ASCII value is an even number.
I know how to sum all the values but the even numbers part is challenging.
def sumString(st):
if not st:
return 0
else:
return ord(st[0]+sumString(st[1:])]
I tried something but i am just confused at this point.
def sumString(st):
if not st:
return 0
t=[ord(st[0]),sumString(st[1:])]
for item in t:
if item%2==0:
return item+t
Maybe something like this?
def sumString(st):
if not st:
return 0
else:
out = ord(st[0]) if ord(st[0]) % 2 == 0 else 0
return out + sumString(st[1:])
print(sumString("abcd"))
Output:
198
The ASCII value for b is 98 and the ASCII value for d is 100. So 100 + 98 gives you the output.
When posting code which causes an error, make sure to include that error
TypeError: unsupported operand type(s) for +: 'int' and 'list' in this case.
No offense, but the code you have written is a hot mess. You create a list with the ord of the first char, then the output of the function.
I think you then attempt to check if both values are even (not needed), and then return the sum (which you dont do since the return statement is inside the loop).
To do this you only need to check the first value of the string, then hand the rest to the same function
def sumString(st):
if not st:
return 0
out = sumString(st[1:]) # get output of the rest of the string
if ord(st[0]) % 2 == 0: # check if first char in str is even
out += ord(st[0])
return out
Here a method recursive and non:
def recursive_sum_even_ascii(s):
if s:
first, *other = s
value = 0
if not ord(first) % 2:
value = ord(first)
return value + recursive_sum_even_ascii(other)
return 0
def sum_even_ascii(s):
return sum(ord(char) for char in s if not ord(char) % 2)
# test
s = "23"
out_rec = recursive_sum_even_ascii(s)
out = sum_even_ascii(s)
print(out_rec == out)

Break a string and reverse each element of it

I'm learning data and algorithm, here is the question I met
Question:Write a short recursive Python function that takes a character string s and
outputs its reverse. For example, the reverse of pots&pans would be
snap&stop .
a="pots&pans"
b=a.split("&")
c=[]
c=list(b)
def reverse(data,leng,leng2,index,count):
rev=(leng-1)-count
if count<leng/2:
temp=data[index][count]
data[index][count]=data[index][rev]
data[index][rev]=temp
if index==leng2:
print(data[index-1]+"&"+data[index])
return reverse(data,leng,leng2,index+1,count)
reverse(c,4,2,0,0)
I got an error here
TypeError: 'str' object does not support item assignment
My initial thought is that str is immutable. So it is better to store it in an list and do the operations. However, it met some problem when I trying to assign str to a list. Any solution to this?
Try this:
a="pots&pans"
b=a.split("&")
def reverse(word):
if not word:
return ""
return reverse(word[1:]) + word[0]
result = reverse(b[1]) + "&" + reverse(b[0])
print(result)
If you want one recursion to also reverse all the words position:
a="pots&pans&hello&hi"
b=a.split("&")
def reverse(lis):
if not lis:
return ""
if type(lis) == list and len(lis) == 1:
return reverse(lis[0])
if type(lis) == str:
return reverse(lis[1:]) + lis[0]
if type(lis) == list:
return reverse(lis[1:]) + "&" + reverse(lis[0])
print(reverse(b))
One recursive approach would be to append the first character to the reverse of the rest of the string:
def rev(s): return rev(s[1:])+s[0] if s else ""
output:
rev("pots&pans")
'snap&stop'
You could also do this without indexing using parameter unpacking:
def rev(first,*rest): return rev(*rest)+first if rest else first
rev(*"pots&pans")
'snap&stop'
Try this:
a="pots&pans"
def reverse(a_string):
`letter_list = list(a_string)`
`letter_list.reverse()`
`return(''.join(letter_list))`
print(reverse(a))

How to return an array of characters in cypher program (python3)

i wrote code when input for example is "a" he return "h". But how i can make it work if i want to return array of characters, for example if is input "aa"
to return "hh"?
def input(s):
for i in range(len(s)):
ci = (ord(s[i])-90)%26+97
s = "".join(chr(ci))
return s
Never use built-in names as input
l = []
def input_x(s):
for i in s:
i = (ord(i)-90)%26+97
l.append(chr(i))
s = ''.join(l)
return s
You can use strings to do this. My variable finaloutput is a string that I will use to store all the updated characters.
def foo(s):
finaloutput = ''
for i in s:
finaloutput += chr((ord(i)-90)%26+97)
return finaloutput
This code uses string concatenation to add together a series of characters. Since strings are iterables, you can use the for loop shown above instead of the complex one that you used.
def input_x(s):
result = ""
for i in s:
ci = (ord(i)-90)%26+ 97
result += chr(ci)
print(result)

Python: can a function return a string?

I am making a recursive function that slices string until it is empty. When it is empty it alternatively selects the characters and is supposed to print or return the value. In this case I am expecting my function to return two words 'Hello' and 'World'. Maybe I have got it all wrong but what I don't understand is that my function doesn't let me print or return string. I am not asking for help but I'd like some explanation :) thanks
def lsubstr(x):
a= ''
b= ''
if x == '':
return ''
else:
a = a + x[0:]
b = b + x[1:]
lsubstr(x[2:])
#print (a,b)
return a and b
lsubstr('hweolrllod')
so I changed my code to this:
def lsubstr(x):
if len(x) <1:
return x
else:
return (lsubstr(x[2:])+str(x[0]),lsubstr(x[2:])+str(x[1]))
lsubstr('hweolrllod')
and what I am trying to make is a tuple which will store 2 pairs of characters and concatenate the next ones,
the error I get is
TypeError: Can't convert 'tuple' object to str implicitly
what exactly is going wrong, I have checked in visualization, it has trouble in concatenating.
The and keyword is a boolean operator, which means it compares two values, and returns one of the values. I think you want to return a tuple instead, like this:
...
return (a, b)
And then you can access the values using the indexing operator like this:
a = lsubstr( ... )
a[0]
a[1]
Or:
word1, word2 = lsubstr( ... )

How do you write a function in Python that takes a string and returns a new string that is the original string with all of the characters repeated?

I am trying to write a function that returns a string that is the inputted string with double characters. For example, if the input was 'hello', then the function should return 'hheelllloo'. I have been trying but I can't seem to find a way to write the function. Any help would be greatly appreciated--Thanks.
With a simple generator:
>>> s = 'hello'
>>> ''.join(c * 2 for c in s)
'hheelllloo'
def repeatChars(text, numOfRepeat):
ans = ''
for c in text:
ans += c * numOfRepeat
return ans
To use:
repeatChars('hello', 2)
output: 'hheelllloo'
Since strings are immutable, it's not a good idea to concatenate them together as seen in the repeatChars method. It's okay if the text you're manipulating has short length like 'hello' but if you're passing 'superfragilisticexpialidocious' (or longer strings)... You get the point. So as an alternative, I've merged my previous code with #Roman Bodnarchuk's code.
Alternate method:
def repeatChars(text, numOfRepeat):
return ''.join([c * numOfRepeat for c in text])
Why? Read this: Efficient String Concatenation in Python
s = 'hello'
''.join(c+c for c in s)
# returns 'hheelllloo'
>>> s = "hello"
>>> "".join(map(str.__add__, s, s))
'hheelllloo'
def doublechar(s):
if s:
return s[0] + s[0] + doublechar(s[1:])
else:
return ""

Categories