title: Schneier's Solitaire Cypher Issues
body: <p>I am trying to implement Schneier's Solitare Cipher in Java and I keep running an issue where I get wrong output when decrypting which means either my encryption logic is wrong or my decryption logic is wrong and I just can't figure it out.</p>
  <p>Here's the code</p>
  <pre><code> package com.alvonellos.util.crypto;
  
  import java.util.Arrays;
  import java.util.HashMap;
  
  public class SchneierSolitaireCypher {
      public enum Card {
          ACESPADE, TWOSPADE, THREESPADE, FOURSPADE, FIVESPADE, SIXSPADE, SEVENSPADE, EIGHTSPADE, NINESPADE, TENSPADE, JACKSPADE, QUEENSPADE, KINGSPADE,
          ACEHEARTS, TWOHEARTS, THREEHEARTS, FOURHEARTS, FIVEHEARTS, SIXHEARTS, SEVENHEARTS, EIGHTHEARTS, NINEHEARTS, TENHEARTS, JACKHEARTS, QUEENHEARTS, KINGHEARTS,
          ACEDIAMONDS, TWODIAMONDS, THREEDIAMONDS, FOURDIAMONDS, FIVEDIAMONDS, SIXDIAMONDS, SEVENDIAMONDS, EIGHTDIAMONDS, NINEDIAMONDS, TENDIAMONDS, JACKDIAMONDS, QUEENDIAMONDS, KINGDIAMONDS,
          ACECLUBS, TWOCLUBS, THREECLUBS, FOURCLUBS, FIVECLUBS, SIXCLUBS, SEVECLUBS, EIGHTCLUBS, NINECLUBS, TENCLUBS, JACKCLUBS, QUEENCLUBS, KINGCLUBS
      }
      public static Card[] getRandomCardDeck() {
          Card[] deck = new Card[52];
          for (int i = 0; i &lt; deck.length; i++) {
              deck[i] = Card.values()[i];
          }
          CryptoAlgorithms.shuffle(deck); // using secure rng
          return deck;
      }
  
      public static String decrypt(String ciphertext, Card[] deck) {
          StringBuffer sb = new StringBuffer(ciphertext.toUpperCase());
  
          int curPos = 0;
          for (int i = 0; i &lt; ciphertext.length(); i++) {
              curPos = i % 52;
              if(ciphertext.charAt(i) == ' ') {
                  sb.setCharAt(i, ' ');
              } else {
                  int tmp = sb.charAt(i) - 'A';    // Offset from 'A'
                  int rotated = (tmp - deck[(ciphertext.length() % deck.length- 1) - i].ordinal()+1) % 26; // Compute rotation, wrap at 26 for chars
                  sb.setCharAt(i, (char) (rotated + 'A'));
              }
          }
  
          return sb.toString();
      }
  
      public static String encrypt(String plaintext, Card[] deck) {
          StringBuffer sb = new StringBuffer(plaintext.toUpperCase());
  
          int curPos = 0;
          for (int i = 0; i &lt; plaintext.length(); i++) {
              curPos = i % 52;
              if(plaintext.charAt(i) == ' ') {
                  sb.setCharAt(i, ' ');
              } else {
                  int tmp = sb.charAt(i) - 'A';    // Offset from 'A'
                  int rotated = (tmp + deck[i].ordinal()+1) % 26; // Compute rotation, wrap at 26 for chars
                  sb.setCharAt(i, (char) (rotated + 'A'));
              }
          }
  
          return sb.toString();
      }
  
  
      public static void main(String[] args) {
          String plaintext = &quot;abcdefghijklmnopqrstuvwxyz&quot;;
          //get a random deck of cards
          Card[] deck = getRandomCardDeck();
  
          //print out the deck of cards
          System.out.println(Arrays.toString(deck));
  
          //encrypt the plaintext
          String ciphertext = encrypt(plaintext, deck);
          System.out.println(ciphertext);
  
          //decrypt the ciphertext
          String decrypted = decrypt(ciphertext, deck);
          System.out.println(decrypted);
      }
  }
  
  </code></pre>
  <p>Here's the console output:</p>
  <pre><code>[KINGHEARTS, QUEENSPADE, ACEHEARTS, FIVESPADE, SIXSPADE, NINESPADE, TWOSPADE, SEVECLUBS, SIXDIAMONDS, EIGHTHEARTS, JACKDIAMONDS, ACEDIAMONDS, FIVEHEARTS, THREECLUBS, THREESPADE, ACECLUBS, EIGHTSPADE, NINEHEARTS, TENCLUBS, FOURCLUBS, FIVEDIAMONDS, SEVENSPADE, NINEDIAMONDS, QUEENHEARTS, TENDIAMONDS, EIGHTCLUBS, SIXCLUBS, KINGSPADE, FOURHEARTS, ACESPADE, EIGHTDIAMONDS, FIVECLUBS, JACKSPADE, SEVENHEARTS, FOURSPADE, TWODIAMONDS, SIXHEARTS, FOURDIAMONDS, TWOHEARTS, KINGCLUBS, QUEENCLUBS, JACKCLUBS, TENHEARTS, SEVENDIAMONDS, THREEDIAMONDS, JACKHEARTS, THREEHEARTS, KINGDIAMONDS, NINECLUBS, TWOCLUBS, QUEENDIAMONDS, TENSPADE]
  ANQIKOIBOEVMEDRDYNPKZCFWIU
  .,:(F2:-;?0L749;F0&gt;KS?CK?=
  </code></pre>
  <p>I'd appreciate it if someone has an idea on how to do the substitution correctly.</p>
  <p>The link to the article is: <a href="https://www.schneier.com/academic/solitaire/" rel="nofollow noreferrer">https://www.schneier.com/academic/solitaire/</a></p>