> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-16/code-analysis/trick-0448.md).

# Reverse Java String Transformation

***

When faced with a custom string transformation or permutation in code (like Java), the core technique is to analyze the logic mapping input indices to output indices. To reverse this, you determine the inverse mapping – where each character in the output came from in the input.

If a permutation `p` maps an element at index `i` to index `p[i]`, its inverse `q` maps the element at index `p[i]` back to index `i`. This relationship is often expressed as `q[p[i]] = i`.

For example, given a permutation represented as a list `p` where `p[i]` is the destination index for the element originally at index `i`, the inverse permutation `q` (where `q[j]` is the original index of the element now at index `j`) can be computed:

```python
def inverse_permutation(p):
    n = len(p)
    q = [0] * n
    for i in range(n):
        q[p[i]] = i
    return q
```

Often, the simplest way to reverse a permutation applied to a string is not to compute the full inverse permutation array first, but rather to directly apply the inverse mapping logic derived from the original transformation rules. This involves writing a script that takes the *final, transformed string* as its input and populates a new buffer (representing the original string) according to this inverse logic.

The provided Python script simulates this reversal. It takes the *transformed output* as the `password` variable and uses the logic derived from the original permutation (paying attention to how input indices map to output indices) to populate its `buffer` array, which reconstructs the original input string. Pay close attention to loop bounds and index arithmetic (`23-i`, `46-i`) when translating the logic.

```python
def checkPassword(password):
  if not len(password) == 32:
    return False
  buffer = [""] * 32

  # Translate the original Java logic to fill buffer (original) from password (transformed)
  # The original mapping was password[source] -> buffer[target]
  # To reverse: buffer[target] = password[source]
  # The indices in the original loop for the Java code were target indices in the output buffer.
  # So, the loop indices (i) here represent the target indices in the *reconstructed original password* (buffer).
  # We need to find where the character at index i in the original password came from in the transformed string.

  # Original Java logic: buffer[i] = password[i] for 0 <= i < 8
  # Reverse: buffer[i] gets char from password[i]
  for i in range(8):
    buffer[i] = password[i]

  # Original Java logic: buffer[i] = password[23 - i] for 8 <= i < 16
  # Reverse: buffer[i] gets char from password[23 - i]
  for i in range(8, 16):
    buffer[i] = password[23 - i]

  # Original Java logic: buffer[i] = password[46 - i] for 16 <= i < 32, step 2
  # Reverse: buffer[i] gets char from password[46 - i]
  for i in range(16, 32, 2):
    buffer[i] = password[46 - i]

  # Original Java logic: buffer[i] = password[i] for 31 >= i >= 16, step -2
  # Reverse: buffer[i] gets char from password[i]
  for i in range(31, 16, -2):
    buffer[i] = password[i]

  print(''.join(buffer)) # Combine and print the reconstructed password

# Use the *known output string* as the input to the reversal script
checkPassword("jU5t_a_sna_3lpm18gb41_u_4_mfr340")
```
