XOR Encryption by Shifting Plaintext

Last Updated : 7 Sep, 2026

A hexadecimal string is encrypted using the following XOR-based cipher.

Let the original string be of length n. Following steps are followed to encrypt it,

  • Consider the original string and repeatedly shift it one position to the right.
  • For each shift, the characters are XORed column-wise with the corresponding characters of the original string.
  • The process continues until all characters of the original string have been used.

Given the encrypted hexadecimal string s, reconstruct and return the original hexadecimal string.

Note: The string contains hexadecimal characters (0-9 and uppercase A-F), and XOR operations are performed on their corresponding hexadecimal values.

Examples:

Input: s = "A1D0A1D"
Output: "ABCD"
Explanation: The original string ABCD is XORed with its successive right-shifted versions, producing the encrypted string A1D0A1D. Hence, the original string is ABCD.

frame_3397

Input: s = "653CAE8DA8EDB426052"
Output: "636F646572"
Explanation: The encrypted string is generated by XORing the original string 636F646572 with its successive right-shifted versions. Therefore, the original string is 636F646572.

Try It Yourself
redirect icon

Using Prefix XOR Approach - O(n) Time and O(1) Space

The encrypted string has 2n - 1 characters, where

  • The first n characters are prefix XORs (A, A ^ B, A ^ B ^ C, A ^ B ^ C ^ D)
  • The remaining n - 1 characters are suffix XORs.

We only need the first n characters for decryption. The first character directly gives the first original character, and XORing two consecutive encrypted characters cancels their common prefix.

  • Calculate the original length as n = (s.length() + 1) / 2.
  • Initialize the answer with the first character s[0], which is the first original character.
  • Traverse the first n characters of the encrypted string from left to right.
  • For each i > 0, XOR the hexadecimal values of s[i-1] and s[i] to recover the ith original character.
  • Convert the resulting value back to a hexadecimal character and append it to the answer.
  • Return the reconstructed original hexadecimal string.
C++
#include <bits/stdc++.h>
using namespace std;

// Convert a hexadecimal character to its integer value.
int hexValue(char ch)
{
    if (ch >= '0' && ch <= '9')
        return ch - '0';

    return ch - 'A' + 10;
}

// Convert an integer value (0-15) to a hexadecimal character.
char hexChar(int x)
{
    if (x <= 9)
        return '0' + x;

    return 'A' + (x - 10);
}

// Decrypt the given encrypted hexadecimal string.
string deCypher(string &s)
{
    // Encrypted string length = 2*n - 1.
    // Therefore, original string length = (length + 1) / 2.
    int n = (s.length() + 1) / 2;

    string ans;

    // The first encrypted character is the first
    // character of the original string.
    ans.push_back(s[0]);

    // Recover the remaining characters using
    // consecutive prefix XOR values.
    for (int i = 1; i < n; i++)
    {
        // XOR consecutive encrypted characters.
        int curr = hexValue(s[i - 1]) ^ hexValue(s[i]);

        // Convert the result back to hexadecimal
        // and add it to the answer.
        ans.push_back(hexChar(curr));
    }

    return ans;
}

int main()
{
    string s = "653CAE8DA8EDB426052";
    string ans = deCypher(s);

    cout << ans << endl;

    return 0;
}
Java
class GFG {

    // Convert a hexadecimal character to its integer value.
    static int hexValue(char ch)
    {
        if (ch >= '0' && ch <= '9')
            return ch - '0';

        return ch - 'A' + 10;
    }

    // Convert an integer value (0-15) to a hexadecimal
    // character.
    static char hexChar(int x)
    {
        if (x <= 9)
            return (char)('0' + x);

        return (char)('A' + (x - 10));
    }

    // Decrypt the given encrypted hexadecimal string.
    static String deCypher(String s)
    {
        // Encrypted string length = 2*n - 1.
        // Therefore, original string length = (length + 1)
        // / 2.
        int n = (s.length() + 1) / 2;

        StringBuilder ans = new StringBuilder();

        // The first encrypted character is the first
        // character of the original string.
        ans.append(s.charAt(0));

        // Recover the remaining characters using
        // consecutive prefix XOR values.
        for (int i = 1; i < n; i++) {

            // XOR consecutive encrypted characters.
            int curr = hexValue(s.charAt(i - 1))
                       ^ hexValue(s.charAt(i));

            // Convert the result back to hexadecimal
            // and add it to the answer.
            ans.append(hexChar(curr));
        }

        return ans.toString();
    }

    public static void main(String[] args)
    {
        String s = "653CAE8DA8EDB426052";
        String ans = deCypher(s);

        System.out.println(ans);
    }
}
Python
# Convert a hexadecimal character to its integer value.
def hexValue(ch):
    if '0' <= ch <= '9':
        return ord(ch) - ord('0')

    return ord(ch) - ord('A') + 10


# Convert an integer value (0-15) to a hexadecimal character.
def hexChar(x):
    if x <= 9:
        return chr(x + ord('0'))

    return chr(x - 10 + ord('A'))


# Decrypt the given encrypted hexadecimal string.
def deCypher(s):

    # Encrypted string length = 2*n - 1.
    # Therefore, original string length = (length + 1) / 2.
    n = (len(s) + 1) // 2

    ans = ""

    # The first encrypted character is the first
    # character of the original string.
    ans += s[0]

    # Recover the remaining characters using
    # consecutive prefix XOR values.
    for i in range(1, n):

        # XOR consecutive encrypted characters.
        curr = hexValue(s[i - 1]) ^ hexValue(s[i])

        # Convert the result back to hexadecimal
        # and add it to the answer.
        ans += hexChar(curr)

    return ans


# Driver Code
if __name__ == "__main__":
    s = "653CAE8DA8EDB426052"
    ans = deCypher(s)
    print(ans)
C#
using System;

class GFG {
    
    // Convert a hexadecimal character to its integer value.
    static int hexValue(char ch)
    {
        if (ch >= '0' && ch <= '9')
            return ch - '0';

        return ch - 'A' + 10;
    }

    // Convert an integer value (0-15) to a hexadecimal
    // character.
    static char hexChar(int x)
    {
        if (x <= 9)
            return (char)('0' + x);

        return (char)('A' + (x - 10));
    }

    // Decrypt the given encrypted hexadecimal string.
    static string deCypher(string s)
    {
        // Encrypted string length = 2*n - 1.
        // Therefore, original string length = (length + 1)
        // / 2.
        int n = (s.Length + 1) / 2;

        string ans = "";

        // The first encrypted character is the first
        // character of the original string.
        ans += s[0];

        // Recover the remaining characters using
        // consecutive prefix XOR values.
        for (int i = 1; i < n; i++) {
            
            // XOR consecutive encrypted characters.
            int curr = hexValue(s[i - 1]) ^ hexValue(s[i]);

            // Convert the result back to hexadecimal
            // and add it to the answer.
            ans += hexChar(curr);
        }

        return ans;
    }

    static void Main()
    {
        string s = "653CAE8DA8EDB426052";
        string ans = deCypher(s);

        Console.WriteLine(ans);
    }
}
JavaScript
// Convert a hexadecimal character to its integer value.
function hexValue(ch)
{
    if (ch >= "0" && ch <= "9")
        return ch.charCodeAt(0) - "0".charCodeAt(0);

    return ch.charCodeAt(0) - "A".charCodeAt(0) + 10;
}

// Convert an integer value (0-15) to a hexadecimal
// character.
function hexChar(x)
{
    if (x <= 9)
        return String.fromCharCode(x + "0".charCodeAt(0));

    return String.fromCharCode(x - 10 + "A".charCodeAt(0));
}

// Decrypt the given encrypted hexadecimal string.
function deCypher(s)
{
    // Encrypted string length = 2*n - 1.
    // Therefore, original string length = (length + 1) / 2.
    let n = Math.floor((s.length + 1) / 2);

    let ans = "";

    // The first encrypted character is the first
    // character of the original string.
    ans += s[0];

    // Recover the remaining characters using
    // consecutive prefix XOR values.
    for (let i = 1; i < n; i++) {

        // XOR consecutive encrypted characters.
        let curr = hexValue(s[i - 1]) ^ hexValue(s[i]);

        // Convert the result back to hexadecimal
        // and add it to the answer.
        ans += hexChar(curr);
    }

    return ans;
}

// Driver Code

let s = "653CAE8DA8EDB426052";
let ans = deCypher(s);

console.log(ans);

Output
636F646572
Comment