Given a string S created by a cypher algorithm. Find the original hexadecimal string.
The cypher algorithm: A hexadecimal string is XORed, N number of times, where N is the string length and every XOR operation is done after shifting the consecutive string to the right.
For example : String: "abcd".  
 
Example 1:
Input:
S = A1D0A1D
Output:
ABCD
Explanation:
Look at the matrix given in the problem statement.
Example 2:
Input:
S = 653CABEBD24
Output:
556F64
Explanation:
556F64
 556F64
  556F64
   556F64
    556F64
     556F64
653CABEBD24
Your Task:
You don't need to read input or print anything. Your task is to complete the function deCypher() which takes the string S as input parameter and returns the original hexadecimal string.
Note: Alphabets are in uppercase.
Expected Time Complexity: O(N)
Expected Space Complexity: O(N)
 
Constraints:
1<=N<=1001 & N%2=1

Source: geeksforgeeks | Difficulty: EASY
Tags: String algorithms

Bit manipulation

Data structures

Starter code: #User function Template for python3
class Solution:
    def deCypher (self, S):
        # Code here

Solutions:
class Solution:

	def deCypher(self, S):
		plain = ''
		x = 0
		l = len(S)
		for i in range(l - 1, int(l / 2) - 1, -1):
			y = x ^ int(S[i], 16)
			x = x ^ y
			plain = hex(y)[-1] + plain
		return plain.upper()


class Solution:

	def str_xor(self, a, b):
		num1 = self.c_num(a)
		num2 = self.c_num(b)
		return self.c_str(num1 ^ num2)

	def c_num(self, a):
		if a >= '0' and a <= '9':
			return int(a)
		else:
			return 10 + (ord(a) - ord('A'))

	def c_str(self, a):
		if a >= 0 and a <= 9:
			return str(a)
		else:
			return chr(ord('A') + (a - 10))

	def deCypher(self, S):
		n = len(S)
		new_len = (n + 1) // 2
		new_s = S[n - 1]
		i = n - 2
		while i >= n - new_len:
			new_s = self.str_xor(S[i], S[i + 1]) + new_s
			i -= 1
		return new_s