PHP、JAVA、C#、Object-C、Android 通用的DES加密解密【仅记录,未验证】

PHP加密解密:

[php]  view plain  copy
  1. class JoDES {  
  2.   
  3.    
  4.   
  5.     private static $_instance = NULL;  
  6.   
  7.     /** 
  8.  
  9.      * @return JoDES 
  10.  
  11.      */  
  12.   
  13.     public static function share() {  
  14.   
  15.         if (is_null(self::$_instance)) {  
  16.   
  17.             self::$_instance = new JoDES();  
  18.   
  19.         }  
  20.   
  21.         return self::$_instance;  
  22.   
  23.     }  
  24.   
  25.    
  26.   
  27.     /** 
  28.  
  29.      * 加密 
  30.  
  31.      * @param string $str 要处理的字符串 
  32.  
  33.      * @param string $key 加密Key,为8个字节长度 
  34.  
  35.      * @return string 
  36.  
  37.      */  
  38.   
  39.     public function encode($str$key) {  
  40.   
  41.         $size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);  
  42.   
  43.         $str = $this->pkcs5Pad($str$size);  
  44.   
  45.         $aaa = mcrypt_cbc(MCRYPT_DES, $key$str, MCRYPT_ENCRYPT, $key);  
  46.   
  47.         $ret = base64_encode($aaa);  
  48.   
  49.         return $ret;  
  50.   
  51.     }  
  52.   
  53.    
  54.   
  55.     /** 
  56.  
  57.      * 解密  
  58.  
  59.      * @param string $str 要处理的字符串 
  60.  
  61.      * @param string $key 解密Key,为8个字节长度 
  62.  
  63.      * @return string 
  64.  
  65.      */  
  66.   
  67.     public function decode($str$key) {  
  68.   
  69.         $strBin = base64_decode($str);  
  70.   
  71.         $str = mcrypt_cbc(MCRYPT_DES, $key$strBin, MCRYPT_DECRYPT, $key);  
  72.   
  73.         $str = $this->pkcs5Unpad($str);  
  74.   
  75.         return $str;  
  76.   
  77.     }  
  78.   
  79.    
  80.   
  81.     function hex2bin($hexData) {  
  82.   
  83.         $binData = "";  
  84.   
  85.         for ($i = 0; $i < strlen($hexData); $i += 2) {  
  86.   
  87.             $binData .= chr(hexdec(substr($hexData$i, 2)));  
  88.   
  89.         }  
  90.   
  91.         return $binData;  
  92.   
  93.     }  
  94.   
  95.    
  96.   
  97.     function pkcs5Pad($text$blocksize) {  
  98.   
  99.         $pad = $blocksize - (strlen($text) % $blocksize);  
  100.   
  101.         return $text . str_repeat(chr($pad), $pad);  
  102.   
  103.     }  
  104.   
  105.    
  106.   
  107.     function pkcs5Unpad($text) {  
  108.   
  109.         $pad = ord($text {strlen($text) - 1});  
  110.   
  111.         if ($pad > strlen($text))  
  112.   
  113.             return false;  
  114.   
  115.    
  116.   
  117.         if (strspn($textchr($pad), strlen($text) - $pad) != $pad)  
  118.   
  119.             return false;  
  120.   
  121.    
  122.   
  123.         return substr($text, 0, - 1 * $pad);  
  124.   
  125.     }  
  126.   
  127.    
  128.   
  129. }  


C#加密解密:

[csharp]  view plain  copy
  1. public class MyDes  
  2.   
  3.     {  
  4.   
  5.         /// <summary>  
  6.   
  7.         /// DES加密方法  
  8.   
  9.         /// </summary>  
  10.   
  11.         /// <param name="strPlain">明文</param>  
  12.   
  13.         /// <param name="strDESKey">密钥</param>  
  14.   
  15.         /// <param name="strDESIV">向量</param>  
  16.   
  17.         /// <returns>密文</returns>  
  18.   
  19.         public static string Encode(string source, string _DESKey)  
  20.   
  21.         {  
  22.   
  23.             StringBuilder sb = new StringBuilder();  
  24.   
  25.             using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())  
  26.   
  27.             {  
  28.   
  29.                 byte[] key = ASCIIEncoding.ASCII.GetBytes(_DESKey);  
  30.   
  31.                 byte[] iv = ASCIIEncoding.ASCII.GetBytes(_DESKey);  
  32.   
  33.                 byte[] dataByteArray = Encoding.UTF8.GetBytes(source);  
  34.   
  35.                 des.Mode = System.Security.Cryptography.CipherMode.CBC;  
  36.   
  37.                 des.Key = key;  
  38.   
  39.                 des.IV = iv;  
  40.   
  41.                 string encrypt = "";  
  42.   
  43.                 using (MemoryStream ms = new MemoryStream())  
  44.   
  45.                 using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))  
  46.   
  47.                 {  
  48.   
  49.                     cs.Write(dataByteArray, 0, dataByteArray.Length);  
  50.   
  51.                     cs.FlushFinalBlock();  
  52.   
  53.                     encrypt = Convert.ToBase64String(ms.ToArray());  
  54.   
  55.                 }  
  56.   
  57.                 return encrypt;  
  58.   
  59.             }  
  60.   
  61.         }  
  62.   
  63.    
  64.   
  65.         /// <summary>  
  66.   
  67.         /// 进行DES解密。  
  68.   
  69.         /// </summary>  
  70.   
  71.         /// <param name="pToDecrypt">要解密的base64串</param>  
  72.   
  73.         /// <param name="sKey">密钥,且必须为8位。</param>  
  74.   
  75.         /// <returns>已解密的字符串。</returns>  
  76.   
  77.         public static string Decode(string source, string sKey)  
  78.   
  79.         {  
  80.   
  81.             byte[] inputByteArray = System.Convert.FromBase64String(source);  
[csharp]  view plain  copy
  1.     //Encoding.UTF8.GetBytes(source);  
  2.   
  3.     using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())  
  4.   
  5.     {  
  6.   
  7.         des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  
  8.   
  9.         des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);  
  10.   
  11.         System.IO.MemoryStream ms = new System.IO.MemoryStream();  
  12.   
  13.         using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))  
  14.   
  15.         {  
  16.   
  17.             cs.Write(inputByteArray, 0, inputByteArray.Length);  
  18.   
  19.             cs.FlushFinalBlock();  
  20.   
  21.             cs.Close();  
  22.   
  23.         }  
  24.   
  25.         string str = Encoding.UTF8.GetString(ms.ToArray());  
  26.   
  27.         ms.Close();  
  28.   
  29.         return str;  
  30.   
  31.     }  
  32.   
  33. }  

JAVA & Android:

[java]  view plain  copy
  1. package com.example.aric.test;  
  2.   
  3.    
  4.   
  5. import javax.crypto.Cipher;  
  6.   
  7. import javax.crypto.SecretKey;  
  8.   
  9. import javax.crypto.SecretKeyFactory;  
  10.   
  11. import javax.crypto.spec.DESKeySpec;  
  12.   
  13. import javax.crypto.spec.IvParameterSpec;  
  14.   
  15.    
  16.   
  17. import android.util.Base64;  
  18.   
  19.    
  20.   
  21. public class DES {  
  22.   
  23.    
  24.   
  25.     public final static String DES_KEY_STRING = "ABSujsuu";  
  26.   
  27.        
  28.   
  29.     public static String encrypt(String message, String key) throws Exception {  
  30.   
  31.         Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");  
  32.   
  33.    
  34.   
  35.         DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));  
  36.   
  37.    
  38.   
  39.         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");  
  40.   
  41.         SecretKey secretKey = keyFactory.generateSecret(desKeySpec);  
  42.   
  43.         IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));  
  44.   
  45.         cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);  
  46.   
  47.    
  48.   
  49.         return encodeBase64(cipher.doFinal(message.getBytes("UTF-8")));  
  50.   
  51.     }  
  52.   
  53.    
  54.   
  55.     public static String decrypt(String message, String key) throws Exception {  
  56.   
  57.    
  58.   
  59.         byte[] bytesrc = decodeBase64(message);//convertHexString(message);  
  60.   
  61.         Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");  
  62.   
  63.         DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));  
  64.   
  65.         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");  
  66.   
  67.         SecretKey secretKey = keyFactory.generateSecret(desKeySpec);  
  68.   
  69.         IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));  
  70.   
  71.    
  72.   
  73.         cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);  
  74.   
  75.    
  76.   
  77.         byte[] retByte = cipher.doFinal(bytesrc);  
  78.   
  79.         return new String(retByte);  
  80.   
  81.     }  
  82.   
  83.    
  84.   
  85.     public static byte[] convertHexString(String ss) {  
  86.   
  87.         byte digest[] = new byte[ss.length() / 2];  
  88.   
  89.         for (int i = 0; i < digest.length; i++) {  
  90.   
  91.             String byteString = ss.substring(2 * i, 2 * i + 2);  
  92.   
  93.             int byteValue = Integer.parseInt(byteString, 16);  
  94.   
  95.             digest[i] = (byte) byteValue;  
  96.   
  97.         }  
  98.   
  99.    
  100.   
  101.         return digest;  
  102.   
  103.     }  
  104.   
  105.    
  106.   
  107.     public static String toHexString(byte b[]) {  
  108.   
  109.         StringBuffer hexString = new StringBuffer();  
  110.   
  111.         for (int i = 0; i < b.length; i++) {  
  112.   
  113.             String plainText = Integer.toHexString(0xff & b[i]);  
  114.   
  115.             if (plainText.length() < 2)  
  116.   
  117.                 plainText = "0" + plainText;  
  118.   
  119.             hexString.append(plainText);  
  120.   
  121.         }  
  122.   
  123.    
  124.   
  125.         return hexString.toString();  
  126.   
  127.     }  
  128.   
  129.    
  130.   
  131.        
  132.   
  133.     public static String encodeBase64(byte[] b) {  
  134.   
  135.         return Base64.encodeToString(b, Base64.DEFAULT);  
  136.   
  137.     }  
  138.   
  139.        
  140.   
  141.     public static byte[] decodeBase64(String base64String) {  
  142.   
  143.         return Base64.decode(base64String, Base64.DEFAULT);  
  144.   
  145.     }  
  146.   
  147. }  


java所需Base64类:

[java]  view plain  copy
  1. /* 
  2.  * Copyright (C) 2010 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package com.myfund.cxf.utils;  
  18.   
  19. import java.io.UnsupportedEncodingException;  
  20.   
  21. /** 
  22.  * Utilities for encoding and decoding the Base64 representation of 
  23.  * binary data.  See RFCs <a 
  24.  * href="http://www.ietf.org/rfc/rfc2045.txt">2045</a> and <a 
  25.  * href="http://www.ietf.org/rfc/rfc3548.txt">3548</a>. 
  26.  */  
  27. public class Base64 {  
  28.     /** 
  29.      * Default values for encoder/decoder flags. 
  30.      */  
  31.     public static final int DEFAULT = 0;  
  32.   
  33.     /** 
  34.      * Encoder flag bit to omit the padding '=' characters at the end 
  35.      * of the output (if any). 
  36.      */  
  37.     public static final int NO_PADDING = 1;  
  38.   
  39.     /** 
  40.      * Encoder flag bit to omit all line terminators (i.e., the output 
  41.      * will be on one long line). 
  42.      */  
  43.     public static final int NO_WRAP = 2;  
  44.   
  45.     /** 
  46.      * Encoder flag bit to indicate lines should be terminated with a 
  47.      * CRLF pair instead of just an LF.  Has no effect if {@code 
  48.      * NO_WRAP} is specified as well. 
  49.      */  
  50.     public static final int CRLF = 4;  
  51.   
  52.     /** 
  53.      * Encoder/decoder flag bit to indicate using the "URL and 
  54.      * filename safe" variant of Base64 (see RFC 3548 section 4) where 
  55.      * {@code -} and {@code _} are used in place of {@code +} and 
  56.      * {@code /}. 
  57.      */  
  58.     public static final int URL_SAFE = 8;  
  59.   
  60.     /** 
  61.      * Flag to pass to {@link Base64OutputStream} to indicate that it 
  62.      * should not close the output stream it is wrapping when it 
  63.      * itself is closed. 
  64.      */  
  65.     public static final int NO_CLOSE = 16;  
  66.   
  67.     //  --------------------------------------------------------  
  68.     //  shared code  
  69.     //  --------------------------------------------------------  
  70.   
  71.     /* package */ static abstract class Coder {  
  72.         public byte[] output;  
  73.         public int op;  
  74.   
  75.         /** 
  76.          * Encode/decode another block of input data.  this.output is 
  77.          * provided by the caller, and must be big enough to hold all 
  78.          * the coded data.  On exit, this.opwill be set to the length 
  79.          * of the coded data. 
  80.          * 
  81.          * @param finish true if this is the final call to process for 
  82.          *        this object.  Will finalize the coder state and 
  83.          *        include any final bytes in the output. 
  84.          * 
  85.          * @return true if the input so far is good; false if some 
  86.          *         error has been detected in the input stream.. 
  87.          */  
  88.         public abstract boolean process(byte[] input, int offset, int len, boolean finish);  
  89.   
  90.         /** 
  91.          * @return the maximum number of bytes a call to process() 
  92.          * could produce for the given number of input bytes.  This may 
  93.          * be an overestimate. 
  94.          */  
  95.         public abstract int maxOutputSize(int len);  
  96.     }  
  97.   
  98.     //  --------------------------------------------------------  
  99.     //  decoding  
  100.     //  --------------------------------------------------------  
  101.   
  102.     /** 
  103.      * Decode the Base64-encoded data in input and return the data in 
  104.      * a new byte array. 
  105.      * 
  106.      * <p>The padding '=' characters at the end are considered optional, but 
  107.      * if any are present, there must be the correct number of them. 
  108.      * 
  109.      * @param str    the input String to decode, which is converted to 
  110.      *               bytes using the default charset 
  111.      * @param flags  controls certain features of the decoded output. 
  112.      *               Pass {@code DEFAULT} to decode standard Base64. 
  113.      * 
  114.      * @throws IllegalArgumentException if the input contains 
  115.      * incorrect padding 
  116.      */  
  117.     public static byte[] decode(String str, int flags) {  
  118.         return decode(str.getBytes(), flags);  
  119.     }  
  120.   
  121.     /** 
  122.      * Decode the Base64-encoded data in input and return the data in 
  123.      * a new byte array. 
  124.      * 
  125.      * <p>The padding '=' characters at the end are considered optional, but 
  126.      * if any are present, there must be the correct number of them. 
  127.      * 
  128.      * @param input the input array to decode 
  129.      * @param flags  controls certain features of the decoded output. 
  130.      *               Pass {@code DEFAULT} to decode standard Base64. 
  131.      * 
  132.      * @throws IllegalArgumentException if the input contains 
  133.      * incorrect padding 
  134.      */  
  135.     public static byte[] decode(byte[] input, int flags) {  
  136.         return decode(input, 0, input.length, flags);  
  137.     }  
  138.   
  139.     /** 
  140.      * Decode the Base64-encoded data in input and return the data in 
  141.      * a new byte array. 
  142.      * 
  143.      * <p>The padding '=' characters at the end are considered optional, but 
  144.      * if any are present, there must be the correct number of them. 
  145.      * 
  146.      * @param input  the data to decode 
  147.      * @param offset the position within the input array at which to start 
  148.      * @param len    the number of bytes of input to decode 
  149.      * @param flags  controls certain features of the decoded output. 
  150.      *               Pass {@code DEFAULT} to decode standard Base64. 
  151.      * 
  152.      * @throws IllegalArgumentException if the input contains 
  153.      * incorrect padding 
  154.      */  
  155.     public static byte[] decode(byte[] input, int offset, int len, int flags) {  
  156.         // Allocate space for the most data the input could represent.  
  157.         // (It could contain less if it contains whitespace, etc.)  
  158.         Decoder decoder = new Decoder(flags, new byte[len*3/4]);  
  159.   
  160.         if (!decoder.process(input, offset, len, true)) {  
  161.             throw new IllegalArgumentException("bad base-64");  
  162.         }  
  163.   
  164.         // Maybe we got lucky and allocated exactly enough output space.  
  165.         if (decoder.op == decoder.output.length) {  
  166.             return decoder.output;  
  167.         }  
  168.   
  169.         // Need to shorten the array, so allocate a new one of the  
  170.         // right size and copy.  
  171.         byte[] temp = new byte[decoder.op];  
  172.         System.arraycopy(decoder.output, 0, temp, 0, decoder.op);  
  173.         return temp;  
  174.     }  
  175.   
  176.     /* package */ static class Decoder extends Coder {  
  177.         /** 
  178.          * Lookup table for turning bytes into their position in the 
  179.          * Base64 alphabet. 
  180.          */  
  181.         private static final int DECODE[] = {  
  182.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  183.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  184.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -162, -1, -1, -163,  
  185.             52535455565758596061, -1, -1, -1, -2, -1, -1,  
  186.             -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  91011121314,  
  187.             1516171819202122232425, -1, -1, -1, -1, -1,  
  188.             -1262728293031323334353637383940,  
  189.             4142434445464748495051, -1, -1, -1, -1, -1,  
  190.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  191.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  192.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  193.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  194.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  195.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  196.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  197.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  198.         };  
  199.   
  200.         /** 
  201.          * Decode lookup table for the "web safe" variant (RFC 3548 
  202.          * sec. 4) where - and _ replace + and /. 
  203.          */  
  204.         private static final int DECODE_WEBSAFE[] = {  
  205.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  206.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  207.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -162, -1, -1,  
  208.             52535455565758596061, -1, -1, -1, -2, -1, -1,  
  209.             -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  91011121314,  
  210.             1516171819202122232425, -1, -1, -1, -163,  
  211.             -1262728293031323334353637383940,  
  212.             4142434445464748495051, -1, -1, -1, -1, -1,  
  213.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  214.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  215.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  216.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  217.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  218.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  219.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  220.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  221.         };  
  222.   
  223.         /** Non-data values in the DECODE arrays. */  
  224.         private static final int SKIP = -1;  
  225.         private static final int EQUALS = -2;  
  226.   
  227.         /** 
  228.          * States 0-3 are reading through the next input tuple. 
  229.          * State 4 is having read one '=' and expecting exactly 
  230.          * one more. 
  231.          * State 5 is expecting no more data or padding characters 
  232.          * in the input. 
  233.          * State 6 is the error state; an error has been detected 
  234.          * in the input and no future input can "fix" it. 
  235.          */  
  236.         private int state;   // state number (0 to 6)  
  237.         private int value;  
  238.   
  239.         final private int[] alphabet;  
  240.   
  241.         public Decoder(int flags, byte[] output) {  
  242.             this.output = output;  
  243.   
  244.             alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;  
  245.             state = 0;  
  246.             value = 0;  
  247.         }  
  248.   
  249.         /** 
  250.          * @return an overestimate for the number of bytes {@code 
  251.          * len} bytes could decode to. 
  252.          */  
  253.         public int maxOutputSize(int len) {  
  254.             return len * 3/4 + 10;  
  255.         }  
  256.   
  257.         /** 
  258.          * Decode another block of input data. 
  259.          * 
  260.          * @return true if the state machine is still healthy.  false if 
  261.          *         bad base-64 data has been detected in the input stream. 
  262.          */  
  263.         public boolean process(byte[] input, int offset, int len, boolean finish) {  
  264.             if (this.state == 6return false;  
  265.   
  266.             int p = offset;  
  267.             len += offset;  
  268.   
  269.             // Using local variables makes the decoder about 12%  
  270.             // faster than if we manipulate the member variables in  
  271.             // the loop.  (Even alphabet makes a measurable  
  272.             // difference, which is somewhat surprising to me since  
  273.             // the member variable is final.)  
  274.             int state = this.state;  
  275.             int value = this.value;  
  276.             int op = 0;  
  277.             final byte[] output = this.output;  
  278.             final int[] alphabet = this.alphabet;  
  279.   
  280.             while (p < len) {  
  281.                 // Try the fast path:  we're starting a new tuple and the  
  282.                 // next four bytes of the input stream are all data  
  283.                 // bytes.  This corresponds to going through states  
  284.                 // 0-1-2-3-0.  We expect to use this method for most of  
  285.                 // the data.  
  286.                 //  
  287.                 // If any of the next four bytes of input are non-data  
  288.                 // (whitespace, etc.), value will end up negative.  (All  
  289.                 // the non-data values in decode are small negative  
  290.                 // numbers, so shifting any of them up and or'ing them  
  291.                 // together will result in a value with its top bit set.)  
  292.                 //  
  293.                 // You can remove this whole block and the output should  
  294.                 // be the same, just slower.  
  295.                 if (state == 0) {  
  296.                     while (p+4 <= len &&  
  297.                            (value = ((alphabet[input[p] & 0xff] << 18) |  
  298.                                      (alphabet[input[p+1] & 0xff] << 12) |  
  299.                                      (alphabet[input[p+2] & 0xff] << 6) |  
  300.                                      (alphabet[input[p+3] & 0xff]))) >= 0) {  
  301.                         output[op+2] = (byte) value;  
  302.                         output[op+1] = (byte) (value >> 8);  
  303.                         output[op] = (byte) (value >> 16);  
  304.                         op += 3;  
  305.                         p += 4;  
  306.                     }  
  307.                     if (p >= len) break;  
  308.                 }  
  309.   
  310.                 // The fast path isn't available -- either we've read a  
  311.                 // partial tuple, or the next four input bytes aren't all  
  312.                 // data, or whatever.  Fall back to the slower state  
  313.                 // machine implementation.  
  314.   
  315.                 int d = alphabet[input[p++] & 0xff];  
  316.   
  317.                 switch (state) {  
  318.                 case 0:  
  319.                     if (d >= 0) {  
  320.                         value = d;  
  321.                         ++state;  
  322.                     } else if (d != SKIP) {  
  323.                         this.state = 6;  
  324.                         return false;  
  325.                     }  
  326.                     break;  
  327.   
  328.                 case 1:  
  329.                     if (d >= 0) {  
  330.                         value = (value << 6) | d;  
  331.                         ++state;  
  332.                     } else if (d != SKIP) {  
  333.                         this.state = 6;  
  334.                         return false;  
  335.                     }  
  336.                     break;  
  337.   
  338.                 case 2:  
  339.                     if (d >= 0) {  
  340.                         value = (value << 6) | d;  
  341.                         ++state;  
  342.                     } else if (d == EQUALS) {  
  343.                         // Emit the last (partial) output tuple;  
  344.                         // expect exactly one more padding character.  
  345.                         output[op++] = (byte) (value >> 4);  
  346.                         state = 4;  
  347.                     } else if (d != SKIP) {  
  348.                         this.state = 6;  
  349.                         return false;  
  350.                     }  
  351.                     break;  
  352.   
  353.                 case 3:  
  354.                     if (d >= 0) {  
  355.                         // Emit the output triple and return to state 0.  
  356.                         value = (value << 6) | d;  
  357.                         output[op+2] = (byte) value;  
  358.                         output[op+1] = (byte) (value >> 8);  
  359.                         output[op] = (byte) (value >> 16);  
  360.                         op += 3;  
  361.                         state = 0;  
  362.                     } else if (d == EQUALS) {  
  363.                         // Emit the last (partial) output tuple;  
  364.                         // expect no further data or padding characters.  
  365.                         output[op+1] = (byte) (value >> 2);  
  366.                         output[op] = (byte) (value >> 10);  
  367.                         op += 2;  
  368.                         state = 5;  
  369.                     } else if (d != SKIP) {  
  370.                         this.state = 6;  
  371.                         return false;  
  372.                     }  
  373.                     break;  
  374.   
  375.                 case 4:  
  376.                     if (d == EQUALS) {  
  377.                         ++state;  
  378.                     } else if (d != SKIP) {  
  379.                         this.state = 6;  
  380.                         return false;  
  381.                     }  
  382.                     break;  
  383.   
  384.                 case 5:  
  385.                     if (d != SKIP) {  
  386.                         this.state = 6;  
  387.                         return false;  
  388.                     }  
  389.                     break;  
  390.                 }  
  391.             }  
  392.   
  393.             if (!finish) {  
  394.                 // We're out of input, but a future call could provide  
  395.                 // more.  
  396.                 this.state = state;  
  397.                 this.value = value;  
  398.                 this.op = op;  
  399.                 return true;  
  400.             }  
  401.   
  402.             // Done reading input.  Now figure out where we are left in  
  403.             // the state machine and finish up.  
  404.   
  405.             switch (state) {  
  406.             case 0:  
  407.                 // Output length is a multiple of three.  Fine.  
  408.                 break;  
  409.             case 1:  
  410.                 // Read one extra input byte, which isn't enough to  
  411.                 // make another output byte.  Illegal.  
  412.                 this.state = 6;  
  413.                 return false;  
  414.             case 2:  
  415.                 // Read two extra input bytes, enough to emit 1 more  
  416.                 // output byte.  Fine.  
  417.                 output[op++] = (byte) (value >> 4);  
  418.                 break;  
  419.             case 3:  
  420.                 // Read three extra input bytes, enough to emit 2 more  
  421.                 // output bytes.  Fine.  
  422.                 output[op++] = (byte) (value >> 10);  
  423.                 output[op++] = (byte) (value >> 2);  
  424.                 break;  
  425.             case 4:  
  426.                 // Read one padding '=' when we expected 2.  Illegal.  
  427.                 this.state = 6;  
  428.                 return false;  
  429.             case 5:  
  430.                 // Read all the padding '='s we expected and no more.  
  431.                 // Fine.  
  432.                 break;  
  433.             }  
  434.   
  435.             this.state = state;  
  436.             this.op = op;  
  437.             return true;  
  438.         }  
  439.     }  
  440.   
  441.     //  --------------------------------------------------------  
  442.     //  encoding  
  443.     //  --------------------------------------------------------  
  444.   
  445.     /** 
  446.      * Base64-encode the given data and return a newly allocated 
  447.      * String with the result. 
  448.      * 
  449.      * @param input  the data to encode 
  450.      * @param flags  controls certain features of the encoded output. 
  451.      *               Passing {@code DEFAULT} results in output that 
  452.      *               adheres to RFC 2045. 
  453.      */  
  454.     public static String encodeToString(byte[] input, int flags) {  
  455.         try {  
  456.             return new String(encode(input, flags), "US-ASCII");  
  457.         } catch (UnsupportedEncodingException e) {  
  458.             // US-ASCII is guaranteed to be available.  
  459.             throw new AssertionError(e);  
  460.         }  
  461.     }  
  462.   
  463.     /** 
  464.      * Base64-encode the given data and return a newly allocated 
  465.      * String with the result. 
  466.      * 
  467.      * @param input  the data to encode 
  468.      * @param offset the position within the input array at which to 
  469.      *               start 
  470.      * @param len    the number of bytes of input to encode 
  471.      * @param flags  controls certain features of the encoded output. 
  472.      *               Passing {@code DEFAULT} results in output that 
  473.      *               adheres to RFC 2045. 
  474.      */  
  475.     public static String encodeToString(byte[] input, int offset, int len, int flags) {  
  476.         try {  
  477.             return new String(encode(input, offset, len, flags), "US-ASCII");  
  478.         } catch (UnsupportedEncodingException e) {  
  479.             // US-ASCII is guaranteed to be available.  
  480.             throw new AssertionError(e);  
  481.         }  
  482.     }  
  483.   
  484.     /** 
  485.      * Base64-encode the given data and return a newly allocated 
  486.      * byte[] with the result. 
  487.      * 
  488.      * @param input  the data to encode 
  489.      * @param flags  controls certain features of the encoded output. 
  490.      *               Passing {@code DEFAULT} results in output that 
  491.      *               adheres to RFC 2045. 
  492.      */  
  493.     public static byte[] encode(byte[] input, int flags) {  
  494.         return encode(input, 0, input.length, flags);  
  495.     }  
  496.   
  497.     /** 
  498.      * Base64-encode the given data and return a newly allocated 
  499.      * byte[] with the result. 
  500.      * 
  501.      * @param input  the data to encode 
  502.      * @param offset the position within the input array at which to 
  503.      *               start 
  504.      * @param len    the number of bytes of input to encode 
  505.      * @param flags  controls certain features of the encoded output. 
  506.      *               Passing {@code DEFAULT} results in output that 
  507.      *               adheres to RFC 2045. 
  508.      */  
  509.     public static byte[] encode(byte[] input, int offset, int len, int flags) {  
  510.         Encoder encoder = new Encoder(flags, null);  
  511.   
  512.         // Compute the exact length of the array we will produce.  
  513.         int output_len = len / 3 * 4;  
  514.   
  515.         // Account for the tail of the data and the padding bytes, if any.  
  516.         if (encoder.do_padding) {  
  517.             if (len % 3 > 0) {  
  518.                 output_len += 4;  
  519.             }  
  520.         } else {  
  521.             switch (len % 3) {  
  522.                 case 0break;  
  523.                 case 1: output_len += 2break;  
  524.                 case 2: output_len += 3break;  
  525.             }  
  526.         }  
  527.   
  528.         // Account for the newlines, if any.  
  529.         if (encoder.do_newline && len > 0) {  
  530.             output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) *  
  531.                 (encoder.do_cr ? 2 : 1);  
  532.         }  
  533.   
  534.         encoder.output = new byte[output_len];  
  535.         encoder.process(input, offset, len, true);  
  536.   
  537.         assert encoder.op == output_len;  
  538.   
  539.         return encoder.output;  
  540.     }  
  541.   
  542.     /* package */ static class Encoder extends Coder {  
  543.         /** 
  544.          * Emit a new line every this many output tuples.  Corresponds to 
  545.          * a 76-character line length (the maximum allowable according to 
  546.          * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>). 
  547.          */  
  548.         public static final int LINE_GROUPS = 19;  
  549.   
  550.         /** 
  551.          * Lookup table for turning Base64 alphabet positions (6 bits) 
  552.          * into output bytes. 
  553.          */  
  554.         private static final byte ENCODE[] = {  
  555.             'A''B''C''D''E''F''G''H''I''J''K''L''M''N''O''P',  
  556.             'Q''R''S''T''U''V''W''X''Y''Z''a''b''c''d''e''f',  
  557.             'g''h''i''j''k''l''m''n''o''p''q''r''s''t''u''v',  
  558.             'w''x''y''z''0''1''2''3''4''5''6''7''8''9''+''/',  
  559.         };  
  560.   
  561.         /** 
  562.          * Lookup table for turning Base64 alphabet positions (6 bits) 
  563.          * into output bytes. 
  564.          */  
  565.         private static final byte ENCODE_WEBSAFE[] = {  
  566.             'A''B''C''D''E''F''G''H''I''J''K''L''M''N''O''P',  
  567.             'Q''R''S''T''U''V''W''X''Y''Z''a''b''c''d''e''f',  
  568.             'g''h''i''j''k''l''m''n''o''p''q''r''s''t''u''v',  
  569.             'w''x''y''z''0''1''2''3''4''5''6''7''8''9''-''_',  
  570.         };  
  571.   
  572.         final private byte[] tail;  
  573.         /* package */ int tailLen;  
  574.         private int count;  
  575.   
  576.         final public boolean do_padding;  
  577.         final public boolean do_newline;  
  578.         final public boolean do_cr;  
  579.         final private byte[] alphabet;  
  580.   
  581.         public Encoder(int flags, byte[] output) {  
  582.             this.output = output;  
  583.   
  584.             do_padding = (flags & NO_PADDING) == 0;  
  585.             do_newline = (flags & NO_WRAP) == 0;  
  586.             do_cr = (flags & CRLF) != 0;  
  587.             alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;  
  588.   
  589.             tail = new byte[2];  
  590.             tailLen = 0;  
  591.   
  592.             count = do_newline ? LINE_GROUPS : -1;  
  593.         }  
  594.   
  595.         /** 
  596.          * @return an overestimate for the number of bytes {@code 
  597.          * len} bytes could encode to. 
  598.          */  
  599.         public int maxOutputSize(int len) {  
  600.             return len * 8/5 + 10;  
  601.         }  
  602.   
  603.         public boolean process(byte[] input, int offset, int len, boolean finish) {  
  604.             // Using local variables makes the encoder about 9% faster.  
  605.             final byte[] alphabet = this.alphabet;  
  606.             final byte[] output = this.output;  
  607.             int op = 0;  
  608.             int count = this.count;  
  609.   
  610.             int p = offset;  
  611.             len += offset;  
  612.             int v = -1;  
  613.   
  614.             // First we need to concatenate the tail of the previous call  
  615.             // with any input bytes available now and see if we can empty  
  616.             // the tail.  
  617.   
  618.             switch (tailLen) {  
  619.                 case 0:  
  620.                     // There was no tail.  
  621.                     break;  
  622.   
  623.                 case 1:  
  624.                     if (p+2 <= len) {  
  625.                         // A 1-byte tail with at least 2 bytes of  
  626.                         // input available now.  
  627.                         v = ((tail[0] & 0xff) << 16) |  
  628.                             ((input[p++] & 0xff) << 8) |  
  629.                             (input[p++] & 0xff);  
  630.                         tailLen = 0;  
  631.                     };  
  632.                     break;  
  633.   
  634.                 case 2:  
  635.                     if (p+1 <= len) {  
  636.                         // A 2-byte tail with at least 1 byte of input.  
  637.                         v = ((tail[0] & 0xff) << 16) |  
  638.                             ((tail[1] & 0xff) << 8) |  
  639.                             (input[p++] & 0xff);  
  640.                         tailLen = 0;  
  641.                     }  
  642.                     break;  
  643.             }  
  644.   
  645.             if (v != -1) {  
  646.                 output[op++] = alphabet[(v >> 18) & 0x3f];  
  647.                 output[op++] = alphabet[(v >> 12) & 0x3f];  
  648.                 output[op++] = alphabet[(v >> 6) & 0x3f];  
  649.                 output[op++] = alphabet[v & 0x3f];  
  650.                 if (--count == 0) {  
  651.                     if (do_cr) output[op++] = '\r';  
  652.                     output[op++] = '\n';  
  653.                     count = LINE_GROUPS;  
  654.                 }  
  655.             }  
  656.   
  657.             // At this point either there is no tail, or there are fewer  
  658.             // than 3 bytes of input available.  
  659.   
  660.             // The main loop, turning 3 input bytes into 4 output bytes on  
  661.             // each iteration.  
  662.             while (p+3 <= len) {  
  663.                 v = ((input[p] & 0xff) << 16) |  
  664.                     ((input[p+1] & 0xff) << 8) |  
  665.                     (input[p+2] & 0xff);  
  666.                 output[op] = alphabet[(v >> 18) & 0x3f];  
  667.                 output[op+1] = alphabet[(v >> 12) & 0x3f];  
  668.                 output[op+2] = alphabet[(v >> 6) & 0x3f];  
  669.                 output[op+3] = alphabet[v & 0x3f];  
  670.                 p += 3;  
  671.                 op += 4;  
  672.                 if (--count == 0) {  
  673.                     if (do_cr) output[op++] = '\r';  
  674.                     output[op++] = '\n';  
  675.                     count = LINE_GROUPS;  
  676.                 }  
  677.             }  
  678.   
  679.             if (finish) {  
  680.                 // Finish up the tail of the input.  Note that we need to  
  681.                 // consume any bytes in tail before any bytes  
  682.                 // remaining in input; there should be at most two bytes  
  683.                 // total.  
  684.   
  685.                 if (p-tailLen == len-1) {  
  686.                     int t = 0;  
  687.                     v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;  
  688.                     tailLen -= t;  
  689.                     output[op++] = alphabet[(v >> 6) & 0x3f];  
  690.                     output[op++] = alphabet[v & 0x3f];  
  691.                     if (do_padding) {  
  692.                         output[op++] = '=';  
  693.                         output[op++] = '=';  
  694.                     }  
  695.                     if (do_newline) {  
  696.                         if (do_cr) output[op++] = '\r';  
  697.                         output[op++] = '\n';  
  698.                     }  
  699.                 } else if (p-tailLen == len-2) {  
  700.                     int t = 0;  
  701.                     v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |  
  702.                         (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);  
  703.                     tailLen -= t;  
  704.                     output[op++] = alphabet[(v >> 12) & 0x3f];  
  705.                     output[op++] = alphabet[(v >> 6) & 0x3f];  
  706.                     output[op++] = alphabet[v & 0x3f];  
  707.                     if (do_padding) {  
  708.                         output[op++] = '=';  
  709.                     }  
  710.                     if (do_newline) {  
  711.                         if (do_cr) output[op++] = '\r';  
  712.                         output[op++] = '\n';  
  713.                     }  
  714.                 } else if (do_newline && op > 0 && count != LINE_GROUPS) {  
  715.                     if (do_cr) output[op++] = '\r';  
  716.                     output[op++] = '\n';  
  717.                 }  
  718.   
  719.                 assert tailLen == 0;  
  720.                 assert p == len;  
  721.             } else {  
  722.                 // Save the leftovers in tail to be consumed on the next  
  723.                 // call to encodeInternal.  
  724.   
  725.                 if (p == len-1) {  
  726.                     tail[tailLen++] = input[p];  
  727.                 } else if (p == len-2) {  
  728.                     tail[tailLen++] = input[p];  
  729.                     tail[tailLen++] = input[p+1];  
  730.                 }  
  731.             }  
  732.   
  733.             this.op = op;  
  734.             this.count = count;  
  735.   
  736.             return true;  
  737.         }  
  738.     }  
  739.   
  740.     private Base64() { }   // don't instantiate  
  741. }  



Object-C:


[objc]  view plain  copy
  1. /***  JoDes.h ***/  
  2.   
  3.    
  4.   
  5. #import <Foundation/Foundation.h>  
  6.   
  7. #import <CommonCrypto/CommonDigest.h>  
  8.   
  9. #import <CommonCrypto/CommonCryptor.h>  
  10.   
  11.    
  12.   
  13. @interface JoDes : NSObject  
  14.   
  15.    
  16.   
  17. + (NSString *) encode:(NSString *)str key:(NSString *)key;  
  18.   
  19. + (NSString *) decode:(NSString *)str key:(NSString *)key;  
  20.   
  21.    
  22.   
  23. @end  
  24.   
  25.    
  26.   
  27.    
  28.   
  29. /***  JoDes.m ***/  
  30.   
  31. //  
  32.   
  33. //  XLEncrytHelper.m  
  34.   
  35. //  NewHoldGold  
  36.   
  37. //  
  38.   
  39. //  Created by 梁鑫磊 on 13-12-27.  
  40.   
  41. //  Copyright (c) 2013年 zsgjs. All rights reserved.  
  42.   
  43. //  
  44.   
  45.    
  46.   
  47. #import "JoDes.h"  
  48.   
  49.    
  50.   
  51. @interface JoDes()  
  52.   
  53.    
  54.   
  55. + (NSString *) encodeBase64WithString:(NSString *)strData;  
  56.   
  57. + (NSString *) encodeBase64WithData:(NSData *)objData;  
  58.   
  59. + (NSData *) decodeBase64WithString:(NSString *)strBase64;  
  60.   
  61.    
  62.   
  63. + (NSString *)doCipher:(NSString *)sTextIn key:(NSString *)sKey  
  64.   
  65.                   context:(CCOperation)encryptOrDecrypt;  
  66.   
  67.    
  68.   
  69. @end  
  70.   
  71.    
  72.   
  73. @implementation JoDes  
  74.   
  75.    
  76.   
  77. + (NSString *) encode:(NSString *)str key:(NSString *)key  
  78.   
  79. {  
  80.   
  81.     // doCipher 不能编汉字,所以要进行 url encode  
  82.   
  83.     NSMutableString* str1 = [JoDes urlEncode:str];  
  84.   
  85.     NSMutableString* encode = [NSMutableString stringWithString:[JoDes doCipher:str1 key:key context:kCCEncrypt]];  
  86.   
  87.     [JoDes formatSpecialCharacters:encode];  
  88.   
  89.     return encode;  
  90.   
  91. }  
  92.   
  93.    
  94.   
  95. + (NSString *) decode:(NSString *)str key:(NSString *)key  
  96.   
  97. {  
  98.   
  99.     NSMutableString *str1 = [NSMutableString stringWithString:str];  
  100.   
  101.     [JoDes reformatSpecialCharacters:str1];  
  102.   
  103.     NSString *rt = [JoDes doCipher:str1 key:key context:kCCDecrypt];  
  104.   
  105.     return rt;  
  106.   
  107. }  
  108.   
  109.    
  110.   
  111. + (NSMutableString *)urlEncode:(NSString*)str  
  112.   
  113. {  
  114.   
  115.     NSMutableString* encodeStr = [NSMutableString stringWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];  
  116.   
  117.     [encodeStr replaceOccurrencesOfString:@"+" withString:@"%2B" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [encodeStr length])];  
  118.   
  119.     [encodeStr replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [encodeStr length])];  
  120.   
  121.     return encodeStr;  
  122.   
  123. }  
  124.   
  125.    
  126.   
  127. + (void)formatSpecialCharacters:(NSMutableString *)str  
  128.   
  129. {  
  130.   
  131.     [str replaceOccurrencesOfString:@"+" withString:@"$$" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];  
  132.   
  133.     [str replaceOccurrencesOfString:@"/" withString:@"@@" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];  
  134.   
  135. }  
  136.   
  137.    
  138.   
  139.    
  140.   
  141. + (void)reformatSpecialCharacters:(NSMutableString *)str  
  142.   
  143. {  
  144.   
  145.     [str replaceOccurrencesOfString:@"$$" withString:@"+" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];  
  146.   
  147.     [str replaceOccurrencesOfString:@"@@" withString:@"/" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];  
  148.   
  149. }  
  150.   
  151.    
  152.   
  153. + (NSString *)encodeBase64WithString:(NSString *)strData {  
  154.   
  155.     return [JoDes encodeBase64WithData:[strData dataUsingEncoding:NSUTF8StringEncoding]];  
  156.   
  157. }  
  158.   
  159.    
  160.   
  161.    
  162.   
  163. + (NSString *)encodeBase64WithData:(NSData *)objData {  
  164.   
  165.     NSString *encoding = nil;  
  166.   
  167.     unsigned charchar *encodingBytes = NULL;  
  168.   
  169.     @try {  
  170.   
  171.         static char encodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
  172.   
  173.         static NSUInteger paddingTable[] = {0,2,1};  
  174.   
  175.            
  176.   
  177.         NSUInteger dataLength = [objData length];  
  178.   
  179.         NSUInteger encodedBlocks = (dataLength * 8) / 24;  
  180.   
  181.         NSUInteger padding = paddingTable[dataLength % 3];  
  182.   
  183.         if( padding > 0 ) encodedBlocks++;  
  184.   
  185.         NSUInteger encodedLength = encodedBlocks * 4;  
  186.   
  187.            
  188.   
  189.         encodingBytes = malloc(encodedLength);  
  190.   
  191.         if( encodingBytes != NULL ) {  
  192.   
  193.             NSUInteger rawBytesToProcess = dataLength;  
  194.   
  195.             NSUInteger rawBaseIndex = 0;  
  196.   
  197.             NSUInteger encodingBaseIndex = 0;  
  198.   
  199.             unsigned charchar *rawBytes = (unsigned charchar *)[objData bytes];  
  200.   
  201.             unsigned char rawByte1, rawByte2, rawByte3;  
  202.   
  203.             while( rawBytesToProcess >= 3 ) {  
  204.   
  205.                 rawByte1 = rawBytes[rawBaseIndex];  
  206.   
  207.                 rawByte2 = rawBytes[rawBaseIndex+1];  
  208.   
  209.                 rawByte3 = rawBytes[rawBaseIndex+2];  
  210.   
  211.                 encodingBytes[encodingBaseIndex] = encodingTable[((rawByte1 >> 2) & 0x3F)];  
  212.   
  213.                 encodingBytes[encodingBaseIndex+1] = encodingTable[((rawByte1 << 4) & 0x30) | ((rawByte2 >> 4) & 0x0F) ];  
  214.   
  215.                 encodingBytes[encodingBaseIndex+2] = encodingTable[((rawByte2 << 2) & 0x3C) | ((rawByte3 >> 6) & 0x03) ];  
  216.   
  217.                 encodingBytes[encodingBaseIndex+3] = encodingTable[(rawByte3 & 0x3F)];  
  218.   
  219.                    
  220.   
  221.                 rawBaseIndex += 3;  
  222.   
  223.                 encodingBaseIndex += 4;  
  224.   
  225.                 rawBytesToProcess -= 3;  
  226.   
  227.             }  
  228.   
  229.             rawByte2 = 0;  
  230.   
  231.             switch (dataLength-rawBaseIndex) {  
  232.   
  233.                 case 2:  
  234.   
  235.                     rawByte2 = rawBytes[rawBaseIndex+1];  
  236.   
  237.                 case 1:  
  238.   
  239.                     rawByte1 = rawBytes[rawBaseIndex];  
  240.   
  241.                     encodingBytes[encodingBaseIndex] = encodingTable[((rawByte1 >> 2) & 0x3F)];  
  242.   
  243.                     encodingBytes[encodingBaseIndex+1] = encodingTable[((rawByte1 << 4) & 0x30) | ((rawByte2 >> 4) & 0x0F) ];  
  244.   
  245.                     encodingBytes[encodingBaseIndex+2] = encodingTable[((rawByte2 << 2) & 0x3C) ];  
  246.   
  247.                     // we can skip rawByte3 since we have a partial block it would always be 0  
  248.   
  249.                     break;  
  250.   
  251.             }  
  252.   
  253.             // compute location from where to begin inserting padding, it may overwrite some bytes from the partial block encoding  
  254.   
  255.             // if their value was 0 (cases 1-2).  
  256.   
  257.             encodingBaseIndex = encodedLength - padding;  
  258.   
  259.             while( padding-- > 0 ) {  
  260.   
  261.                 encodingBytes[encodingBaseIndex++] = '=';  
  262.   
  263.             }  
  264.   
  265.             encoding = [[NSString alloc] initWithBytes:encodingBytes length:encodedLength encoding:NSASCIIStringEncoding];  
  266.   
  267.         }  
  268.   
  269.     }  
  270.   
  271.     @catch (NSException *exception) {  
  272.   
  273.         encoding = nil;  
  274.   
  275.         NSLog(@"WARNING: error occured while tring to encode base 32 data: %@", exception);  
  276.   
  277.     }  
  278.   
  279.     @finally {  
  280.   
  281.         if( encodingBytes != NULL ) {  
  282.   
  283.             free( encodingBytes );  
  284.   
  285.         }  
  286.   
  287.     }  
  288.   
  289.     return encoding;  
  290.   
  291.        
  292.   
  293. }  
  294.   
  295.    
  296.   
  297. + (NSData *)decodeBase64WithString:(NSString *)strBase64 {  
  298.   
  299.     NSData *data = nil;  
  300.   
  301.     unsigned charchar *decodedBytes = NULL;  
  302.   
  303.     @try {  
  304.   
  305. #define __ 255  
  306.   
  307.         static char decodingTable[256] = {  
  308.   
  309.             __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x00 - 0x0F  
  310.   
  311.             __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x10 - 0x1F  
  312.   
  313.             __,__,__,__, __,__,__,__, __,__,__,62, __,__,__,63,  // 0x20 - 0x2F  
  314.   
  315.             52,53,54,5556,57,58,5960,61,__,__, __, 0,__,__,  // 0x30 - 0x3F  
  316.   
  317.             __, 012,  3456,  789,1011,12,13,14,  // 0x40 - 0x4F  
  318.   
  319.             15,16,17,1819,20,21,2223,24,25,__, __,__,__,__,  // 0x50 - 0x5F  
  320.   
  321.             __,26,27,2829,30,31,3233,34,35,3637,38,39,40,  // 0x60 - 0x6F  
  322.   
  323.             41,42,43,4445,46,47,4849,50,51,__, __,__,__,__,  // 0x70 - 0x7F  
  324.   
  325.             __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x80 - 0x8F  
  326.   
  327.             __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x90 - 0x9F  
  328.   
  329.             __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xA0 - 0xAF  
  330.   
  331.             __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xB0 - 0xBF  
  332.   
  333.             __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xC0 - 0xCF  
  334.   
  335.             __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xD0 - 0xDF  
  336.   
  337.             __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xE0 - 0xEF  
  338.   
  339.             __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xF0 - 0xFF  
  340.   
  341.         };  
  342.   
  343.         strBase64 = [strBase64 stringByReplacingOccurrencesOfString:@"=" withString:@""];  
  344.   
  345.         NSData *encodedData = [strBase64 dataUsingEncoding:NSASCIIStringEncoding];  
  346.   
  347.         unsigned charchar *encodedBytes = (unsigned charchar *)[encodedData bytes];  
  348.   
  349.            
  350.   
  351.         NSUInteger encodedLength = [encodedData length];  
  352.   
  353.         NSUInteger encodedBlocks = (encodedLength+3) >> 2;  
  354.   
  355.         NSUInteger expectedDataLength = encodedBlocks * 3;  
  356.   
  357.            
  358.   
  359.         unsigned char decodingBlock[4];  
  360.   
  361.            
  362.   
  363.         decodedBytes = malloc(expectedDataLength);  
  364.   
  365.         if( decodedBytes != NULL ) {  
  366.   
  367.                
  368.   
  369.             NSUInteger i = 0;  
  370.   
  371.             NSUInteger j = 0;  
  372.   
  373.             NSUInteger k = 0;  
  374.   
  375.             unsigned char c;  
  376.   
  377.             while( i < encodedLength ) {  
  378.   
  379.                 c = decodingTable[encodedBytes[i]];  
  380.   
  381.                 i++;  
  382.   
  383.                 if( c != __ ) {  
  384.   
  385.                     decodingBlock[j] = c;  
  386.   
  387.                     j++;  
  388.   
  389.                     if( j == 4 ) {  
  390.   
  391.                         decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);  
  392.   
  393.                         decodedBytes[k+1] = (decodingBlock[1] << 4) | (decodingBlock[2] >> 2);  
  394.   
  395.                         decodedBytes[k+2] = (decodingBlock[2] << 6) | (decodingBlock[3]);  
  396.   
  397.                         j = 0;  
  398.   
  399.                         k += 3;  
  400.   
  401.                     }  
  402.   
  403.                 }  
  404.   
  405.             }  
  406.   
  407.                
  408.   
  409.             // Process left over bytes, if any  
  410.   
  411.             if( j == 3 ) {  
  412.   
  413.                 decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);  
  414.   
  415.                 decodedBytes[k+1] = (decodingBlock[1] << 4) | (decodingBlock[2] >> 2);  
  416.   
  417.                 k += 2;  
  418.   
  419.             } else if( j == 2 ) {  
  420.   
  421.                 decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);  
  422.   
  423.                 k += 1;  
  424.   
  425.             }  
  426.   
  427.             data = [[NSData alloc] initWithBytes:decodedBytes length:k];  
  428.   
  429.         }  
  430.   
  431.     }  
  432.   
  433.     @catch (NSException *exception) {  
  434.   
  435.         data = nil;  
  436.   
  437.         NSLog(@"WARNING: error occured while decoding base 32 string: %@", exception);  
  438.   
  439.     }  
  440.   
  441.     @finally {  
  442.   
  443.         if( decodedBytes != NULL ) {  
  444.   
  445.             free( decodedBytes );  
  446.   
  447.         }  
  448.   
  449.     }  
  450.   
  451.     return data;  
  452.   
  453.        
  454.   
  455. }  
  456.   
  457.    
  458.   
  459.    
  460.   
  461. + (NSString *)doCipher:(NSString *)sTextIn key:(NSString *)sKey  
  462.   
  463.                   context:(CCOperation)encryptOrDecrypt {  
  464.   
  465.     NSStringEncoding EnC = NSUTF8StringEncoding;  
  466.   
  467.        
  468.   
  469.     NSMutableData *dTextIn;  
  470.   
  471.     if (encryptOrDecrypt == kCCDecrypt) {  
  472.   
  473.         dTextIn = [[JoDes decodeBase64WithString:sTextIn] mutableCopy];  
  474.   
  475.     }  
  476.   
  477.     else{  
  478.   
  479.         dTextIn = [[sTextIn dataUsingEncoding: EnC] mutableCopy];  
  480.   
  481.     }  
  482.   
  483.     NSMutableData * dKey = [[sKey dataUsingEncoding:EnC] mutableCopy];  
  484.   
  485.     [dKey setLength:kCCBlockSizeDES];  
  486.   
  487.     uint8_t *bufferPtr1 = NULL;  
  488.   
  489.     size_t bufferPtrSize1 = 0;  
  490.   
  491.     size_t movedBytes1 = 0;  
  492.   
  493.     //uint8_t iv[kCCBlockSizeDES];  
  494.   
  495.     //memset((void *) iv, 0x0, (size_t) sizeof(iv));  
  496.   
  497.     //    Byte iv[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};  
  498.   
  499.     bufferPtrSize1 = ([sTextIn length] + kCCKeySizeDES) & ~(kCCKeySizeDES -1);  
  500.   
  501.     bufferPtr1 = malloc(bufferPtrSize1 * sizeof(uint8_t));  
  502.   
  503.     memset((voidvoid *)bufferPtr10x00, bufferPtrSize1);  
  504.   
  505.        
  506.   
  507.     CCCrypt(encryptOrDecrypt, // CCOperation op  
  508.   
  509.             kCCAlgorithmDES, // CCAlgorithm alg  
  510.   
  511.             kCCOptionPKCS7Padding, // CCOptions options  
  512.   
  513.             [dKey bytes], // const void *key  
  514.   
  515.             [dKey length], // size_t keyLength //  
  516.   
  517.             [dKey bytes], // const void *iv  
  518.   
  519.             [dTextIn bytes], // const void *dataIn  
  520.   
  521.             [dTextIn length],  // size_t dataInLength  
  522.   
  523.             (voidvoid *)bufferPtr1// void *dataOut  
  524.   
  525.             bufferPtrSize1,     // size_t dataOutAvailable  
  526.   
  527.             &movedBytes1);  
  528.   
  529.        
  530.   
  531.     //[dTextIn release];  
  532.   
  533.     //[dKey release];  
  534.   
  535.        
  536.   
  537.     NSString * sResult;  
  538.   
  539.     if (encryptOrDecrypt == kCCDecrypt){  
  540.   
  541.         sResult = [[NSString alloc] initWithData:[NSData dataWithBytes:bufferPtr1 length:movedBytes1] encoding:EnC];  
  542.   
  543.         free(bufferPtr1);  
  544.   
  545.     }  
  546.   
  547.     else {  
  548.   
  549.         NSData *dResult = [NSData dataWithBytes:bufferPtr1 length:movedBytes1];  
  550.   
  551.         free(bufferPtr1);  
  552.   
  553.         sResult = [JoDes encodeBase64WithData:dResult];  
  554.   
  555.     }  
  556.   
  557.     return sResult;  
  558.   
  559. }  
  560.   
  561.    
  562. @end  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值