/**
 * The {@code Jummania} class demonstrates AES encryption key reconstruction and
 * decryption of a string that was obfuscated using character shifting and Base64 encoding.
 * <p>
 * This is an example of lightweight obfuscation layered on top of symmetric encryption,
 * suitable for scenarios where additional obscurity is desired beyond encryption.
 * 
 * <p><b>Note:</b> This code is for educational or internal use only and not recommended for
 * production-grade cryptographic implementations.
 * 
 * <p><b>Created by:</b> Jummania  
 * <br><b>Date:</b> 28/1/26
 * <br><b>Email:</b> sharifuddinjumman@gmail.com  
 * <br><b>Location:</b> Dhaka, Bangladesh
 */
public class Jummania {


    /**
     * Retrieves the decrypted original string using hardcoded obfuscated input and a predefined secret key.
     * <p>
     * This method uses a hardcoded string as the AES key (in obfuscated form) and another hardcoded
     * string as the encrypted input. It reconstructs the AES {@link javax.crypto.SecretKey} from the key,
     * then decrypts the encrypted input (which has been character-shifted and Base64-encoded) to return
     * the original plain text.
     *
     * @return the decrypted original plain text
     * @throws Exception if any error occurs during secret key reconstruction or decryption
     */
    public String getString() throws Exception {
        return getString("ZNRCronnQuKwL,i[mZB7NB", "KfhwiA6YuLJ@h/wH/v6PQP");
    }
    
    
     /**
     * Decrypts an obfuscated and Base64-encoded string using AES with the provided secret key.
     * <p>
     * The decryption process involves three steps:
     * <ol>
     *   <li>Reverse the character shift applied during encryption (each character is decremented by 1).</li>
     *   <li>Decode the result from Base64 to obtain the original encrypted bytes.</li>
     *   <li>Decrypt the bytes using the AES algorithm and the given secret key.</li>
     * </ol>
     *
     * @param secretKey     the string used to derive the AES {@link javax.crypto.SecretKey} for decryption
     * @param encryptedText the input string that was obfuscated, Base64-encoded, and AES-encrypted
     * @return the original plaintext string after successful decryption
     * @throws Exception if any step of the decryption process fails (e.g., Base64 decoding, cipher setup, or AES decryption)
     */
    private String getString(String secretKey, String encryptedText) throws Exception {
        String string = shiftChars(encryptedText, 1);
        java.util.Base64.Decoder decoder = java.util.Base64.getDecoder();
        byte[] encryptedTextByte = decoder.decode(string);
        javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES");
        cipher.init(javax.crypto.Cipher.DECRYPT_MODE, getSecretKey(secretKey));
        return new String(cipher.doFinal(encryptedTextByte));
    }


    /**
     * Converts an obfuscated Base64-encoded AES key string into a SecretKey object.
     * The input string is shifted by -1 on each character before Base64 decoding.
     * 
     * @param key The obfuscated Base64-encoded AES key string
     * @return SecretKey instance for AES algorithm
     */
    private javax.crypto.SecretKey getSecretKey(String key) {
        String string = shiftChars(key, -1);
        byte[] decodedKey = java.util.Base64.getDecoder().decode(string);
        return new javax.crypto.spec.SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
    }


    /**
     * Applies a character-wise shift to each character in the input string.
     * For each character c, returns (char)(c + shift).
     * 
     * @param input The input string to be shifted
     * @param shift The integer shift to apply (positive or negative)
     * @return The shifted string after applying the character shift
     */
    private String shiftChars(String input, int shift) {
        StringBuilder result = new StringBuilder();
        for (char c : input.toCharArray()) {
            result.append((char) (c + shift));
        }
        return result.toString();
    }
}