1. 程式人生 > >RSA之JS於JAVA互動,廢話不多上程式碼!

RSA之JS於JAVA互動,廢話不多上程式碼!

package org.boyz.rsa.rsajs;

/**
 * Created by on 2015/1/6.
 */

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

/**
 * RSA 工具類。提供加密,解密,生成金鑰對等方法。
 * 需要到http://www.bouncycastle.org下載bcprov-jdk14-123.jar。
 * RSA工具類,主要針對RSA.js使用
 * 用法:
 * 1、使用generateKeyPair()方法生成金鑰檔案
 * 2、公鑰資訊給客戶端使用
 * 3、私鑰資訊給服務端使用
 * 4、客戶端公鑰加密傳給服務端,服務端私鑰解密。
 * 5、服務端私鑰加密傳給客戶端,客戶端公鑰解密。
 * 6、私鑰在任何情況下不能暴露於客戶端。
 */
public class RSAUtil {
    // 生成金鑰檔案
    private static String RSAKeyStore = "C:/RSAKey.txt";
    /**
     * 生成金鑰
     * @return
     * @throws Exception
     */
    public static KeyPair generateKeyPair() throws Exception {
        try {
            KeyPairGenerator keyPairGen =
                    KeyPairGenerator.getInstance("RSA",new BouncyCastleProvider());
            final int KEY_SIZE = 512; // 金鑰大小
            keyPairGen.initialize(KEY_SIZE, new SecureRandom());
            KeyPair keyPair = keyPairGen.generateKeyPair();
            System.out.println(keyPair.getPrivate());
            System.out.println(keyPair.getPublic());
            saveKeyPair(keyPair);
            return keyPair;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 實際使用中不會經常生成金鑰,而是獲取金鑰。金鑰可以定期更換。
     * @return
     * @throws Exception
     */
    public static KeyPair getKeyPair() throws Exception {
        FileInputStream fis = new FileInputStream(RSAKeyStore);
        ObjectInputStream oos = new ObjectInputStream(fis);
        KeyPair kp = (KeyPair) oos.readObject();
        oos.close();
        fis.close();
        return kp;
    }

    /**
     *
     * @param kp
     * @throws Exception
     */
    public static void saveKeyPair(KeyPair kp) throws Exception {
        FileOutputStream fos = new FileOutputStream(RSAKeyStore);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(kp);
        oos.close();
        fos.close();
    }

    /**
     * 生成公鑰
     * @param modulus
     * @param publicExponent
     * @return
     * @throws Exception
     */
    public static RSAPublicKey generateRSAPublicKey(byte[] modulus,
                                                    byte[] publicExponent) throws Exception {
        KeyFactory keyFac = null;
        try {
            keyFac = KeyFactory.getInstance("RSA",new BouncyCastleProvider());
        } catch (NoSuchAlgorithmException ex) {
            throw new Exception(ex.getMessage());
        }
        RSAPublicKeySpec pubKeySpec =
                new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));
        try {
            return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
        } catch (InvalidKeySpecException ex) {
            throw new Exception(ex.getMessage());
        }
    }

    /**
     * 生成私鑰
     * @param modulus
     * @param privateExponent
     * @return
     * @throws Exception
     */
    public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus,
                                                      byte[] privateExponent) throws Exception {
        KeyFactory keyFac = null;
        try {
            keyFac = KeyFactory.getInstance("RSA",
                    new BouncyCastleProvider());
        } catch (NoSuchAlgorithmException ex) {
            throw new Exception(ex.getMessage());
        }
        RSAPrivateKeySpec priKeySpec =
                new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent));
        try {
            return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
        } catch (InvalidKeySpecException ex) {
            throw new Exception(ex.getMessage());
        }
    }

    /**
     * 公鑰加密
     * @param pk
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(PublicKey pk, byte[] data) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance("RSA",
                    new BouncyCastleProvider());
            cipher.init(Cipher.ENCRYPT_MODE, pk);
            int blockSize = cipher.getBlockSize();// 獲得加密塊大小,如:加密前資料為128個byte,而key_size=1024
            // 加密塊大小為127
            // byte,加密後為128個byte;因此共有2個加密塊,第一個127
            // byte第二個為1個byte
            int outputSize = cipher.getOutputSize(data.length);// 獲得加密塊加密後塊大小
            int leavedSize = data.length % blockSize;
            int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
            byte[] raw = new byte[outputSize * blocksSize];
            int i = 0;
            while (data.length - i * blockSize > 0) {
                if (data.length - i * blockSize > blockSize)
                    cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
                else
                    cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
                // 這裡面doUpdate方法不可用,檢視原始碼後發現每次doUpdate後並沒有什麼實際動作除了把byte[]放到
                // ByteArrayOutputStream中,而最後doFinal的時候才將所有的byte[]進行加密,可是到了此時加密塊大小很可能已經超出了
                // OutputSize所以只好用dofinal方法。
                i++;
            }
            return raw;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 私鑰解密
     * @param pk
     * @param raw
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(PrivateKey pk, byte[] raw) throws Exception {
        try {
            Cipher cipher =
                    Cipher.getInstance("RSA",new BouncyCastleProvider());
            cipher.init(cipher.DECRYPT_MODE, pk);
            int blockSize = cipher.getBlockSize();
            ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
            int j = 0;
            while (raw.length - j * blockSize > 0) {
                bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
                j++;
            }
            return bout.toByteArray();
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 私鑰加密
     * @param pk
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(PrivateKey pk, byte[] data) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance("RSA",
                    new BouncyCastleProvider());
            cipher.init(Cipher.ENCRYPT_MODE, pk);
            int blockSize = cipher.getBlockSize();// 獲得加密塊大小,如:加密前資料為128個byte,而key_size=1024
            // 加密塊大小為127
            // byte,加密後為128個byte;因此共有2個加密塊,第一個127
            // byte第二個為1個byte
            int outputSize = cipher.getOutputSize(data.length);// 獲得加密塊加密後塊大小
            int leavedSize = data.length % blockSize;
            int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
            byte[] raw = new byte[outputSize * blocksSize];
            int i = 0;
            while (data.length - i * blockSize > 0) {
                if (data.length - i * blockSize > blockSize)
                    cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
                else
                    cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
                // 這裡面doUpdate方法不可用,檢視原始碼後發現每次doUpdate後並沒有什麼實際動作除了把byte[]放到
                // ByteArrayOutputStream中,而最後doFinal的時候才將所有的byte[]進行加密,可是到了此時加密塊大小很可能已經超出了
                // OutputSize所以只好用dofinal方法。
                i++;
            }
            return raw;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 公鑰解密
     * @param pk
     * @param raw
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(PublicKey pk, byte[] raw) throws Exception {
        try {
            Cipher cipher =
                    Cipher.getInstance("RSA",new BouncyCastleProvider());
            cipher.init(cipher.DECRYPT_MODE, pk);
            int blockSize = cipher.getBlockSize();
            ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
            int j = 0;
            while (raw.length - j * blockSize > 0) {
                bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
                j++;
            }
            return bout.toByteArray();
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 測試
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        RSAPublicKey rsap = (RSAPublicKey) RSAUtil.generateKeyPair().getPublic();
        String test = "hello world";
        byte[] en_test = encrypt(getKeyPair().getPublic(), test.getBytes());
        byte[] de_test = decrypt(getKeyPair().getPrivate(), en_test);
        System.out.println(new String(de_test));
    }
	/* 金鑰資訊
RSA Private CRT Key
            modulus: c1d48e176abd94cd1c575771f89d60932afaa98f6c0ba90667a199f5ca6306ece35695b55cac25583ce9161bcc996f0b329a6c7885c92377f119220fbe9d6c2f
    public exponent: 10001
   private exponent: 252361da50c464576c7fbbac85b339c6d8ec5042bfb3f83dd6eb5ac18276b8e3a2d0e87c6d5eb8c4dcbffc4c98be1a18d4796ed13191a9964dc364c136286f41
             primeP: f78c87c6a7127354f8dcd182e9ae0265ac51fc96a78629352de32a96f4c4e8e1
             primeQ: c8728c0f69c1efc0d05ac705872f220d433449e8ab6b5739f2bd395eeb49a70f
     primeExponentP: 137e8c9eb73f7bb7a0557b664cd2b83b9b836559d3dd7bd74542d372c9d9cbe1
     primeExponentQ: ec0574c5f1515a6d3ee8a4cfed8da21adbb7060fe148533cf885b6b7fd748c3
     crtCoefficient: a5a57bbd95a9b8fec4dcb53102accb4f531980499d9499e9b66b965a050db345

RSA Public Key
            modulus: c1d48e176abd94cd1c575771f89d60932afaa98f6c0ba90667a199f5ca6306ece35695b55cac25583ce9161bcc996f0b329a6c7885c92377f119220fbe9d6c2f
    public exponent: 10001

hello world
	 */



}


package org.boyz.rsa.rsajs;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

/**
 * Created by [email protected] on 2015/1/6.
 * 針對 /rsa/Barrett.js
 *      /rsa/BigInt.js
 *      /rsa/RSA.js
 * 使用的RSA工具類
 */
public class RSAUtilForJS {

    public static void main(String[] args) throws Exception {
        String msg = "你好測試你好測試你好測試1111你好測試你好測試你好測試1111111111你好測試你好測試你好測試1111你好測試你好測試你好測試1111111111";
        String demsg = RSAUtilForJS.encryptToRsaJS(msg);
        System.out.println(demsg);
    }

    /**
     * 私鑰解密RSA.js用公鑰加密的資料
     * 應用於伺服器端
     * @param input
     * @throws Exception
     */
    public static String decyrptFromRsaJS(String input) throws Exception {
        System.out.println("原始資訊:" + input );
        String msg = "" ;
        String[] results = input.split(" ");
        for(int i=0 ;i<results.length ;i++) {
            String result = results[i];
            System.out.println("解密前["+i+"]=" + result);
            //byte[] en_result = new BigInteger(result, 16).toByteArray(); // 此方法有bug採用hexStringToBytes
            byte[] en_result = hexStringToBytes(result);
            byte[] de_result = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(), en_result);
            StringBuffer sbuff = new StringBuffer();
            sbuff.append(new String(de_result));
            String detmp = sbuff.reverse().toString();
            System.out.println("解密後["+i+"]="+detmp);
            msg += detmp;
        }
        System.out.println("DECODE前=" + msg);
        msg = URLDecoder.decode(msg, "UTF-8");
        System.out.println("DECODE後=" + msg);
        return msg ;
    }
    /**
     * 私鑰加密資料,針對RSA.js。
     * 應用於伺服器端
     * @param input
     * @throws Exception
     */
    public static String encryptToRsaJS(String input) throws Exception {
        System.out.println("原始資訊:" + input );
        input = URLEncoder.encode(input, "UTF-8");
        System.out.println("URLEncoder:" + input );
        // 將input拆成長度為62的String加密,在JS中各個解密在拼接後使用decodeURIComponent
        // 62的取值詳見RSA.js中this.chunkSize資訊
        int splitLen = 62;
        int splitCnt = input.length() / splitLen ;
        java.util.ArrayList<String> splitArr = new java.util.ArrayList<String>();
        //迴圈處理62整數倍
        for(int i=0 ; i < splitCnt ; i++){
            String tmp = input.substring(splitLen * i , splitLen * (i + 1) );
            tmp = new StringBuffer().append(tmp).reverse().toString();
            tmp = toHexString(tmp);
            byte[] t = RSAUtil.encrypt(RSAUtil.getKeyPair().getPrivate() , hexStringToBytes(tmp)); // 私鑰加密
            String hexStr = byte2hex(t);
            splitArr.add(hexStr);
        }
        //單獨處理剩餘字串處理
        int splitRem = input.length()%splitLen;
        if( splitRem != 0 ){
            String tmp = input.substring(input.length() - splitRem);
            tmp = new StringBuffer().append(tmp).reverse().toString();
            tmp = toHexString(tmp);
            byte[] t = RSAUtil.encrypt(RSAUtil.getKeyPair().getPrivate() , hexStringToBytes(tmp)); // 私鑰加密
            String hexStr = byte2hex(t);
            splitArr.add(hexStr);
        }
        // 列印測試
        String output = "";
        for(String str : splitArr){
            //System.out.print(str);
            //System.out.print(" ");
            output += str+" " ;
        }
        return output.substring(0, output.length() - 1);
    }

    /**
     * java位元組碼轉字串
     * @param b
     * @return
     */
    public static String byte2hex(byte[] b) { //一個位元組的數,
        // 轉成16進位制字串
        String hs = "";
        String tmp = "";
        for (int n = 0; n < b.length; n++) {
            //整數轉成十六進位制表示
            tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (tmp.length() == 1) {
                hs = hs + "0" + tmp;
            } else {
                hs = hs + tmp;
            }
        }
        tmp = null;
        //return hs.toUpperCase(); //轉成大寫 JS 端不需要轉成大寫
        return hs;
    }

    /**
     * 字串轉java位元組碼
     * @param b
     * @return
     */
    public static byte[] hex2byte(byte[] b) {
        if ((b.length % 2) != 0) {
            throw new IllegalArgumentException("長度不是偶數");
        }
        byte[] b2 = new byte[b.length / 2];
        for (int n = 0; n < b.length; n += 2) {
            String item = new String(b, n, 2);
            // 兩位一組,表示一個位元組,把這樣表示的16進位制字串,還原成一個進位制位元組
            b2[n / 2] = (byte) Integer.parseInt(item, 16);
        }
        b = null;
        return b2;
    }

    public static String toHexString(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = (int) s.charAt(i);
            String s4 = Integer.toHexString(ch);
            str = str + s4;
        }
        return str;
    }

    /**
     * 16進位制 To byte[]
     * @param hexString
     * @return byte[]
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }
    /**
     * Convert char to byte
     * @param c char
     * @return byte
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
}


<%--
  Created by IntelliJ IDEA.
  User: [email protected]
  Date: 2015/1/6
  Time: 16:32
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
    <script type="text/javascript" src="RSA.js?version=<%=Math.random() %>"></script>
    <script type="text/javascript" src="BigInt.js?version=<%=Math.random() %>"></script>
    <script type="text/javascript" src="Barrett.js?version=<%=Math.random() %>"></script>
</head>
<body>
<p>原始資料:<div id="msg1"></div></p>
<p>轉碼資料:<div id="msg2"></div></p>
<p>加密資料:<div id="msg3"></div></p>
<input type="hidden" id="encryptMsg" name="encryptMsg" value=""/>
<input type="button" onclick="encrypt()" value="encrypt">
<input type="button" onclick="postEncryptMsg()" value="encrypt">
<script>
    function postEncryptMsg(){
        var encryptMsg = document.getElementById("encryptMsg").value;
        window.location.href="rsa_demo_2.jsp?msg="+encryptMsg;
    }
    function encrypt(){
        // rsa.js 公鑰加密
        setMaxDigits(130); // 設定數值資料的長度,要在new RSAKeyPair()之前使用
        var modulus = "c1d48e176abd94cd1c575771f89d60932afaa98f6c0ba90667a199f5ca6306ece35695b55cac25583ce9161bcc996f0b329a6c7885c92377f119220fbe9d6c2f";
        var publicExponent = "10001"; // 公鑰指數 即是客戶端加密指數即也是客戶端解密指數
        var encryptPublicKey = new RSAKeyPair(publicExponent,"",modulus); // 加密公鑰
        var msg = "公鑰指數 即是客戶端";
        document.getElementById("msg1").innerHTML=msg;
        //print("原始資料:"+msg);
        msg = encodeURIComponent(msg);
        document.getElementById("msg2").innerHTML=msg;
        //print("轉碼資料:"+msg);
        msg = encryptedString(encryptPublicKey,msg);
        document.getElementById("msg3").innerHTML=msg;
        //print("加密資料:"+msg);

        document.getElementById("encryptMsg").value= msg ;
    }
    function print(msg){
        document.write(msg+"<br/>")
    }

</script>

</body>
</html>

<%--
  Created by IntelliJ IDEA.
  User: [email protected]
  Date: 2015/1/6
  Time: 16:32
  To change this template use File | Settings | File Templates.
--%>
<%@ page import="org.boyz.rsa.rsajs.RSAUtilForJS" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="java.net.URLDecoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<p>JS加密 -> JAVA解密 -> 結果</p>
<%
    String msg = request.getParameter("msg");
    out.print("傳入資訊:"+msg+"<br/>");
    msg = URLDecoder.decode(msg,"UTF-8");
    out.print("轉碼資料:"+msg+"<br/>");
    msg = RSAUtilForJS.decyrptFromRsaJS(msg);
    out.print("解密資料:"+msg+"<br/>");
%>
<hr/>
<p>JAVA加密 -> JS解密 -> 舉例</p>
<%
    String msg2 = "梳理2014年境外媒體、外國政要學者對中國的關注熱詞,也正是世界讀中國的一扇扇視窗。";
    out.print("原始資訊:"+msg2+"<br/>");
    //msg2 = URLEncoder.encode(msg2,"UTF-8"); 此處注意,URL跳轉已經轉碼不要再轉碼
    //out.print("轉碼資訊:"+msg2+"<br/>");
    msg2 = RSAUtilForJS.encryptToRsaJS(msg2);
    out.print("加密資訊:"+msg2+"<br/>");
%>
<input type="button" value="JS解密" onclick="decryptRsaJS()" />
<script>
    function decryptRsaJS(){
        window.location.href = "rsa_demo_3.jsp?msg2=<%=msg2 %>";
    }

</script>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
  User: [email protected]
  Date: 2015/1/6
  Time: 16:32
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
    <script type="text/javascript" src="RSA.js?version=<%=Math.random() %>"></script>
    <script type="text/javascript" src="BigInt.js?version=<%=Math.random() %>"></script>
    <script type="text/javascript" src="Barrett.js?version=<%=Math.random() %>"></script>
</head>
<body>
<%
String msg2 = request.getParameter("msg2");
%>
<p>JAVA加密 -> JS解密 -> 結果</p>
<p><div id="demsg2_1"></div></p>
<p><div id="demsg2_2"></div></p>
<br/>
<input type="button" value="JS解密" onclick="decrypt()"/>
<input type="button" value="再測一次" onclick="javascript:window.location.href=rsa_demo_1.jsp"/>
<script>
    function decrypt(){
        // rsa.js 公鑰解密
        setMaxDigits(130); // 設定數值資料的長度,要在new RSAKeyPair()之前使用
        var modulus = "c1d48e176abd94cd1c575771f89d60932afaa98f6c0ba90667a199f5ca6306ece35695b55cac25583ce9161bcc996f0b329a6c7885c92377f119220fbe9d6c2f";
        var publicExponent = "10001"; // 公鑰指數 即是客戶端加密指數即也是客戶端解密指數
        var decryptPublicKey = new RSAKeyPair("",publicExponent,modulus); // 解密公鑰
        var demsg2_1 = decryptedString(decryptPublicKey,"<%=msg2 %>");
        var demsg2_2 = decodeURIComponent(demsg2_1);
        document.getElementById("demsg2_1").innerHTML= "解密資料:"+demsg2_1 ;
        document.getElementById("demsg2_2").innerHTML= "轉碼資料:"+demsg2_2 ;
    }
</script>

</body>
</html>

資源下載路徑:

http://download.csdn.net/detail/csto_sun/8333679

相關推薦

RSAJSJAVA互動,廢話程式碼

package org.boyz.rsa.rsajs; /** * Created by on 2015/1/6. */ import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax

android webview一篇文章全面瞭解(基本使用,url攔截,jsjava互動

1.前言 最近幾年混合應用越來越流行,及一部分功能用原生程式碼開發,一部分功能用html5實現。那什麼時候用原生什麼時候用網頁呢?很多人第一反應就是經常變化的頁面用網頁開發,避免經常發包,不全對。其實因為網頁使用體驗遠遠不及原生開發,所以一般有以下兩種情況建議

簡單的實現 Jsjava互動

效果:點選img標籤實現圖片的交替顯示,實現需要懂點js,哈哈。 //上程式碼 public class MainActivity extends AppCompatActivity { WebView mWebView; android.os.Handl

前臺js與後臺C#互相呼叫 & JSHTML互動

C#程式碼與javaScript函式的相互呼叫? 問: 1.如何在JavaScript訪問C#函式? 2.如何在JavaScript訪問C#變數? 3.如何在C#中訪問JavaScript的已有變數? 4.如何在C#中訪問JavaScript函式?問題1答案如下: ja

RSA演算法 JS加密 JAVA解密

有這樣一個需求,前端登入的使用者名稱密碼,密碼必需加密,但不可使用MD5,因為後臺要檢測密碼的複雜度,那麼在保證安全的前提下將密碼傳到後臺呢,答案就是使用RSA非對稱加密演算法解決 。 java程式碼 import org.apache.commons.

卅川的狀態機路(創作中,定時傳)

rom 不同的 大學 核心 追溯 選擇 有限狀態機 span 任務 川的第一篇幹貨,將從講述FSM(有限狀態機)開始。 川第一次接觸狀態機這種東西,還得追溯到剛到暢遊工作,破解了別的遊戲的代碼(遊戲程序就是這麽沒節操和底線,嗯!)才知道有這麽個東西的。雖然大學學習過相

想要視頻的進廢話

aid 多說 視頻 ongl 5% hao123 想要 http list %E6%96%B0%E6%89%8B%E5%AD%A6%E4%B9%A0%E7%BC%96%E7%A8%8B%E6%9C%89%E9%82%A3%E4%B9%88%E9%9A%BE%E5%90%97

記錄一下使用支付寶電腦網站支付介面遇到的一些坑 廢話說,總結一下

記錄一下使用支付寶電腦網站支付介面遇到的一些坑 廢話不多說,總結一下: 廢話不多說,總結一下: 1、因為同步和非同步url新增自定義引數(處理後續操作資料庫),弄了一兩天,問了支付寶小哥哥,我聽著也是模稜兩可,最後,自己慢慢測試找到一個方法:如下 //設定同步

vue小技巧偷懶的檔案路徑——減少必要的程式碼

  眾所周知,我們寫vue專案的時候都會建立很多個檔案,尤其是一些中大型專案,會有很深的資料夾,當你去引入的時候,要寫很長的路徑比如我要引入一個css檔案, 必須得  import  '../../../styles/iconfont.css'  ,檔案放的越深,路徑就越長,所以我來說一個小技巧。   當我們

【shiter編寫程式的藝術】大資料生態圈,計算機視覺,機器學習,高階技術的愛好者,話說,程式碼

公眾號:     老王和他的IT界朋友們 歡迎投稿:  [email protected] QQ交流群:  593683975 QQ群提供技術交流,CSDN資源,百度文庫等資源共享 加群問題:拋硬幣正面上的期望? 我們想用一段音樂,幾張圖片, 些

#程式設計師上班戴耳機被批,反懟稱影響敲程式碼網友:是喊你聽不見主管沒面子

很多程式設計師在敲程式碼的時候都喜歡戴著耳機聽音樂,這其中固然有著聽歌能夠幫助敲程式碼的原因在裡面,更多的則是告訴別人:別來打擾我! 如果有想學習java的程式設計師,可來我們的java學習扣qun:943111692,免費送java的視訊教程噢!我整理了一份適合18年學習的java乾貨

shiter編寫程式的藝術(大資料生態圈,計算機視覺,機器學習,高階技術的愛好者,話說,程式碼

公眾號:     老王和他的IT界朋友們 歡迎投稿:  [email protected] QQ交流群:  593683975 QQ群提供技術交流,CSDN資源,百度文庫等資源共享 加群問題:拋硬幣正面上的期望? 我們想用一段音樂,幾張圖片, 些

清華竟然交大全球高校計算機專業排名出爐

程式猿(微訊號:imkuqin) 猿妹 編譯資料參考:http://csrankings.org

angularjsui-bootstrap的Datepicker Popup使用JS實現雙日期選擇控件

function 2.3 spa ots fun 自定義指令 str borde ext 最開始使用ui-bootstrap的Datepicker Popup日期選擇插件實現雙日期選擇時間範圍時,在網上搜了一些通過JS去實現的方法,不過後來發現可以不必通過JS去處理,只需要

JNI c/c++和Java互動,呼叫java成員

public class JniTest2 { //c訪問非靜態成員 public String testField="hello..."; //c修改java靜態成員 public static int time=78; //c訪問java 方

iOS webView的高階用法JS互動

前言:說起JS互動,很多童鞋會黯然色變,感覺很高深的樣子。大部分小夥伴只知道一種,哪一種我也說說吧。    1.在webView中將要請求的時候,攔截URL,進行重定向,然而該場景實用有限,網上資料也很多下面說說另一種互動方式。 - (BOOL)webView:(UIWe

入門 js中axios實現與後臺互動入口

格式略 寫不進去 !!! <script src="js/axios.min.js"></script> <script> window.onload = function(){ // 1.第一種 axios

python中執行緒開啟的兩種方式(內含有event的應用,即安全的機制,類似java的等待喚醒機制,會出現個執行緒之間的錯亂問題)

 event是類似於java中的等待喚醒機制,具體方法參照上一篇CSDN 下面來介紹開啟執行緒的第一種方式 #Filename:threading1.py #開啟執行緒的第一種方式 import threading import time event=threadin

HTML瀏覽者互動

<form method="傳送方式" action="伺服器檔案"> 講解: 1.form :<form>標籤是成對出現的,以<form>開始,以</form>結束。 2.action :瀏覽者輸入

JSJava在對中文進行MD5加密時,一致問題解決

最近和前端同學除錯,發現我這裡總是無法驗證通過,因為他傳給我的MD5和我生成的MD5總是對不上。但是一開始的時候,我是驗證了兩邊的方法的,以test為例在頁面的console中輸入MD5('test')則輸出結果為098f6bcd4621d373cade4e832627b4f