litesoft
@ 947
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
// This Source Code is in the Public Domain per: http://unlicense.org package org.litesoft.encryption.symmetric; public class AlphaNumericConstrainedSymmetricEncryptor extends AbstractSymmetricEncryptor { public static final SymmetricEncryptor INSTANCE = new AlphaNumericConstrainedSymmetricEncryptor(); public String getIdentifierAndVersion() { return "ANCE-1"; } protected Helper createHelper( String pText ) { return new MyHelper( pText ); } private static class MyHelper extends Helper { private int mLastClearTextChar = 'M'; private int mDeltaRunning = 0; private int mCharDeltasRemaining = 0; public MyHelper( String pText ) { super( pText ); } public String done() { if ( mCharDeltasRemaining != 0 ) { throw new DecryptFailureException( (char) ('0' + mCharDeltasRemaining), this.getClass() ); } return toString(); } public void encode( int pChar ) { int zDelta = pChar - mLastClearTextChar; if ( zDelta < 0 ) { LLencode( -zDelta, 'a' ); } else { LLencode( zDelta, 'A' ); } mLastClearTextChar = pChar; } private void LLencode( int pDelta, int pBase ) { if ( div4 <= pDelta ) { mSB.append( '4' ); pDelta = addFactor( pDelta, pBase, div4 ); pDelta = addFactor( pDelta, pBase, div3 ); pDelta = addFactor( pDelta, pBase, div2 ); } else if ( div3 <= pDelta ) { mSB.append( '3' ); pDelta = addFactor( pDelta, pBase, div3 ); pDelta = addFactor( pDelta, pBase, div2 ); } else if ( div2 <= pDelta ) { mSB.append( '2' ); pDelta = addFactor( pDelta, pBase, div2 ); } LLencodeChar( pDelta, pBase ); } private int addFactor( int pDelta, int pBase, int pDivisor ) { int zDelta = 0; while ( pDelta >= pDivisor ) { zDelta++; pDelta -= pDivisor; } LLencodeChar( zDelta, pBase ); return pDelta; } private void LLencodeChar( int pDelta, int pBase ) { mSB.append( (pDelta == 0) ? '0' : (char) (pBase + (pDelta - 1)) ); } // 0 = No Change / same letter // A-Z = Delta: +1 to +26 // a-z = Delta: -1 to -26 // 2-4 = Delta: that many letters/'0' follow, witch are in base 27 private static final int div4 = 19683; // 27 * 27 * 27; private static final int div3 = 729; // 27 * 27; private static final int div2 = 27; public void decode( int pChar ) { if ( mCharDeltasRemaining > 0 ) { int zDelta = LLdecode( pChar ); mDeltaRunning = (mDeltaRunning * 27) + zDelta; if ( --mCharDeltasRemaining == 0 ) { LLdecodeChar( mDeltaRunning ); mDeltaRunning = 0; } return; } if ( ('2' <= pChar) && (pChar <= '4') ) { mCharDeltasRemaining = pChar - '0'; return; } LLdecodeChar( LLdecode( pChar ) ); } private void LLdecodeChar( int pDelta ) { mLastClearTextChar += pDelta; mSB.append( (char) mLastClearTextChar ); } private int LLdecode( int pChar ) { if ( pChar == '0' ) { return 0; } if ( ('a' <= pChar) && (pChar <= 'z') ) { return -(1 + (pChar - 'a')); } if ( ('A' <= pChar) && (pChar <= 'Z') ) { return (1 + (pChar - 'A')); } throw new DecryptFailureException( (char) pChar, this.getClass() ); } } } |