springboot+thymeleaf的web項目——古典密碼加密。對後端入門有幫助的小demo

前端(這個是總結的筆記,不是項目,想看項目的,可以翻到第一點的最後,直接有源代碼,註解我寫的挺多的,對你應該有幫助)

  1. 前後端交互方式:
  • 表單
  • ajax
$.ajax({
        type: "post",
        url: "/recws/user/userLogout",
        data: {},
        async : false,
        success: function (data) {//data爲返回json數據
         if(data.result == "success"){
                window.location.replace("/");
         }else{
         }
        }
    });
  • iframe
  1. 控制元素出現和消失:
方法一

利用該方法實現隱藏後,頁面的位置還被控件佔用,顯示空白。

document.getElementById("div3").style.visibility="hidden";
document.getElementById("div4").style.visibility="visible";
<div>visibility:元素的位置仍被佔用</div>
<div id="div3" style="visibility:visible;">DIV 3</div>
<div id="div4" style="visibility:hidden;">DIV 4</div>
方法二

利用該方法實現隱藏後,頁面的位置不被佔用。

document.getElementById("div2").style.display="inline";
document.getElementById("div1").style.display="none";
<div>display:元素的位置不被佔用</div>
<div id="div1" style="display:block;">DIV 1</div>
<div id="div2" style="display:none;">DIV 2</div>
  1. js 操作元素div流程:
  • 元素埋點,html中,對想要操作的元素塊命名id或者name。
  • js代碼區中,通過id,name,或者type來獲取元素:var userDom = document.getElementById(“user”);
  • 操作元素變量進行修改,如修改元素的顯示value值:userDom.value = use;
  • 將操作封裝爲函數
  • html中通過onclick()等方法,埋點綁定函數,實現點擊動態事件等。
  1. js動態修改表單form的action值,實現不同的跳轉:(表單的本質就是發送一個http請求,路由是action的值,參數是表單內的表單控件,其中屬性名是控件的name,值是控件的值。比如input控件的輸入框,給他取名name就是屬性,輸入的值就是屬性值)
方法一

通過對select表單元件綁定函數,實現動態切換路由,主要通過方法:document.getElementById("Searchtype")方法獲得元素塊。要熟悉對象的方法纔可以。

<form id="form1" name="form1" method="post" action="../news/index.asp">
   <table width="100%" height="43" border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td height="28"><input name="keyword" type="text" style="width:150px" id="keyword"/></td>
    </tr>
    <tr>
     <td height="28"><select name="Searchtype" style="width:110px" id="Searchtype" onchange="Searchtype1();">
      <option value="news" selected="selected">新聞中心</option>
      <option value="case">工程案例</option>
     </select>
     <input type="submit" name="Submit" value="搜索" /></td>
    </tr>
   </table>
 </form>
 <script language="javascript">
 function Searchtype1(){
 var type=document.getElementById("Searchtype").options[document.getElementById("Searchtype").selectedIndex].value;
 if (type=="news"){document.getElementById("form1").action="../news/index.asp"}
 else if (type=="case"){document.getElementById("form1").action="../case/index.asp"}
 }
 </script>
方法二

通過對錶單綁定onSubmit()函數,實現動態切換路由,主要通過方法:document.form1.a[0].checked方法判斷轉移條件,是直接通過name操作元素的方式。這要很熟悉每一個對象的內部屬性纔可以。

<html>
<head>
<script language="javascript">
function check(){
if(document.form1.a[0].checked==true)
document.form1.action="1.htm"
else
document.form1.action="2.htm"
}
</script>
</head>
<body>
<form name="form1" method="post" action="" onSubmit="check();">
轉到頁面一<input type="radio" name="a">
轉到頁面二<input type="radio" name="a">
<input name="" type="submit" value="提交">
</form>
</body>
</html> 
  1. 覆蓋已經輸出的內容:
用途:

後臺返回一個數據的時候,可以將內容輸出到一個指定的區域,很多數據都可以放到這個位置,只要重寫這裏面的內容就好,而不需要自己預先建立很多個塊,然後隱藏再顯示什麼的。
方法一
document.write()是在頁面內寫內容,他會覆蓋頁面內容,是寫死的,且document.write會將頁面上的所有內容清除包括標題。

document.write()

方法二
innerHTML只會重寫所屬元素的內容,即

元素中的內容

<script>
		window.onload = function(){
			var ff=document.getElementById("sg");
			ff.innerHTML="<p>I love <em>JavaScript</em>!</p>";
		}
	</script>
  1. 前端ui設置通式:
  • 直接用
    框住,然後配合埋點id加上css就可以實現好看的ui和合適的佈局
  1. 前端執行js代碼的時候,建議寫好算法流程,比如:1.創建數組,2.數組轉化爲string,3.寫好遍歷數組的方法,4.寫好數組運算的方法。即:按照面向過程的方式,一個過程一次測試,通過了再來下一個,而不要幾個過程才進行一次,那樣會導致debug時間增加。
  2. 同理,前端寫css界面的時候也是,不要直接套下整個模板,要一步一步看。

前端源碼:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <style type="text/css">
        body {
            background-image: url(http://gss0.baidu.com/-Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/8ad4b31c8701a18b4c1c626c9a2f07082838fe1a.jpg);
            background-repeat: no-repeat;
            /* 當內容高度大於圖片高度時,背景圖像的位置相對於viewport固定 */
            background-attachment: fixed;
            /*此條屬性必須設置否則可能無效*/
            /* 讓背景圖基於容器大小伸縮 */
            background-size: cover;
            /* 設置背景顏色,背景圖加載過程中會顯示背景色 */
            background-color: #CCCCCC;
        }

        #user_reg {
            font-family: 微軟雅黑;
            font-size: 40px;
            text-align: center;
            margin-top: 100px;
        }

        form {
            width: 600px;
            /*設置寬度,方便使其居中*/
            /*margin: 40px auto auto auto;*/
            /*上右下左*/
            font-size: 25px;
        }

        input {
            height: 30px;
            width: 120px;
            margin-top: 5px;
            margin-bottom: 5px;
        }

        /*input標籤下的屬性選擇器*/

        input[type="submit"],
        input[type="button"] {
            height: 40px;
            width: 130px;
            margin-top: 5px;
            margin-left: 6px;
        }
        input[type="text"]{
            height: 25px;
            width: 430px;
        }
/*文本特效*/
        span {
            color: #d9d9d9;
            position: relative;
            z-index: 1;
        }

        span::before {
            content: "";
            z-index: -1;
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            background: #262626;
            transform-origin: center right;
            transform: scaleX(0);
            transition: transform 0.1s linear;
            /* 這裏不要指明爲 all */
        }

        span:hover {
            cursor: pointer;
        }

        span:hover::before {
            transform-origin: center left;
            transform: scaleX(1);
        }

    </style>

    <script language="javascript" th:inline="javascript">
        function check(){
            if(document.form1.a[0].checked==true){
                document.form1.action="/encryption/caeser";
            }
            if (document.form1.a[1].checked==true){
                document.form1.action="/encryption/caeser/encode";
            }
            if(document.form1.a[2].checked==true)
                document.form1.action="/encryption/playfair"
            if(document.form1.a[3].checked==true)
                document.form1.action="/encryption/playfair/encode"
            if(document.form1.a[4].checked==true)
                document.form1.action="/encryption/hill"
            if(document.form1.a[5].checked==true)
                document.form1.action="/encryption/hill/encode"
        }

        // function check2(){
        //     var userDom = document.getElementById("my");
        //     var use =userDom.value ;
        // }

        function show() {
            if(document.getElementById("div2").style.display=="none"){
                document.getElementById("div2").style.display="inline";
            }
           else{
                document.getElementById("div2").style.display="none";
            }
        // <div id="div1" style="display:block;">DIV 1</div>  block又是什麼狀態??
        }

        function click1() {
            document.getElementById("div3").style.display = "inline";
            var ff = document.getElementById("div3");
            if (document.form1.a[0].checked == true) {
                ff.innerHTML = "<br/>介紹:<br/>凱撒加密,移動位置爲3,支持中文加密";
            }
                if (document.form1.a[1].checked == true) {
                    ff.innerHTML = "<br/>介紹:<br/>凱撒解密,移動位置爲3,支持中文加密";
                }
                if (document.form1.a[2].checked == true)
                    ff.innerHTML = "<br/>介紹:<br/>playfair加密,採用的構成5*5字母表的單詞爲pengyuxia,僅僅支持英文";
                if (document.form1.a[3].checked == true)
                    ff.innerHTML = "<br/>介紹:<br/>playfair解密,採用的構成5*5字母表的單詞爲pengyuxia,僅僅支持英文,注意,輸入的密文肯定是偶數,如果想自己隨意測試自己寫的密文,請輸入偶數位字符串";
                if (document.form1.a[4].checked == true)
                    ff.innerHTML = "<br/>介紹:<br/>hill加密,採用3*3矩陣,支持所有ascii碼,長度任意的字符加密,其中,長度不是3的倍數的字符長度將自動補x";
                if (document.form1.a[5].checked == true)
                    ff.innerHTML = "<br/>介紹:<br/>hill解密,明文不是3的倍數的字符,最後將自動補x,直到爲3的倍數";

        }
            function load() {
                var a = [[${result}]];
                if (a != null) {
                    document.getElementById("div2").style.display = "inline";
                } else {
                    document.getElementById("div2").style.display = "none";
                }
            }

    </script>
</head>
<body onload="load();">

<form name="form1" method="post" action="" onSubmit="check();">
    <table>
        <tr>
            <td><p></p></td>
            <td></td>
        </tr>
    </table>
    <div id="user_reg">古典加密</div><br/>
    <input type="radio" name="a" on  onchange="click1();">---凱撒加密---
<!--    只要一個綁定了,那麼就都綁定了-->
    <input type="radio" name="a" onchange="click1();">---凱撒解密---
    <br>
    <input type="radio" name="a" onchange="click1();">-playfair加密 -
    <input type="radio" name="a" onchange="click1();">-playfair解密 -
    <br>
    <input type="radio" name="a" onchange="click1();">  ---hill加密----
    <input type="radio" name="a" onchange="click1();"> ---hill解密---
    <br/>
    <br/>
    <br/>
    <span>明文/密文:</span><input id="my" type="text" name="front">
    <br/>
    <br/>
    <div align="center">
        <input name="" type="submit" value="提交">
        <input name="display" type="button" value="顯示結果" onclick="show();" >
    </div>

    <div id="div2" style="display:none;">
    <p id="miwen" th:text="'結果:'+ ${result}" ></p>
</div>
    <div id="div3" style="display:inline;">
        <p id="m">使用說明:<br/>選擇加密(或者解密)方式,而後輸入要加密或者解密的文本,點擊執行即可獲得密文(明文)</p>
    </div>
</form>

</body>
</html>

參考項目

  1. css界面參考:https://blog.csdn.net/weixin_41287260/article/details/83474429

後端

springmvc

總體來說,項目中我可以感受到的是:springmvc是控制跳轉的。和我之前寫的前後端分離的項目不一樣的是,這種方式寫出的項目,每次的返回值都是一個modelandview,這種情況帶來的後果就是。每一次都要找到resource中的頁面,然後渲染數據,再返回整個頁面,這種方式,很不ajax,很消耗資源,每次都是重新的渲染。如果你在當前頁面已經有一些狀態和初始不一樣了,那會帶來一些麻煩。不過,因爲是和spring集成的,所以,很自然的就可以用返回json的方式,只要,前端是通過ajax發送的請求,有接收函數即可。

  1. 返回數據的方式:
  • string+model
@RequestMapping("/caeser")
    public String encryptionByCaeser(Model model,@RequestParam String front){
        String ciphertext=encryptByCaeserServer.encrypt(front);
        model.addAttribute("result",ciphertext);
        return "/mi/try";//返回路徑文件也可以,不帶model也可以,好奇怪啊。
    }
  • modelandview
@RequestMapping("/caeser/encode")
    public ModelAndView encodeCaeser(@RequestParam String front){
        ModelAndView modelAndView=new ModelAndView("/mi/try");
        String ciphertext=encryptByCaeserServer.encode(front);
        modelAndView.addObject("result",ciphertext);
        return modelAndView;
    }
  1. 爲了實現ajax,我這沒有用前端的$ajax()函數,而是直接用了表單,然後只要返回的表單地址是同一個值/mi/try,那麼,最終結果顯示再頁面上,看起來就像是ajax一樣了。因爲頁面沒變,渲染數據已經在後臺完成,形成了modelandview再返回的。
  2. 總結前後端交互方式:
前端傳參方式,通過name給屬性命名和賦值,再通過action發送http請求(通過url來處理),而後mvc再返回一個
數據處理了的頁面,這個過程通過modelandview自動再默認的資源文件下查找

後端源碼;
一個controller:

package com.example.dockerjd.Controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.example.dockerjd.passwordService.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @Author: permission
 * @Description:
 * @Date: Create in 20:00 2019/10/28
 * @Modified By:
 */
@Controller
@RequestMapping("/encryption")
public class encryptionController {
    @Autowired
    private encryptByCaeserServer encryptByCaeserServer;
    @Autowired
    private enByHillService enByHillService;
    @Autowired
    private playfairerService playfairerService;
    @RequestMapping(value="/index")
    public ModelAndView index(HttpServletRequest request, HttpServletResponse response){
        return new ModelAndView("/mi/try");
    }
    //request方式獲得參數

    @RequestMapping("/caeser")
    public String encryptionByCaeser(Model model,@RequestParam String front){
        String ciphertext=encryptByCaeserServer.encrypt(front);
        model.addAttribute("result",ciphertext);
        return "/mi/try";//返回路徑文件也可以,不帶model也可以,好奇怪啊。
    }
    //model+string方式
    //@RequestParam方式獲得參數,三種方式,反射,@RequestParam(“屬性名”),對象反射接收多個屬性

    @RequestMapping("/caeser/encode")
    public ModelAndView encodeCaeser(@RequestParam String front){
        ModelAndView modelAndView=new ModelAndView("/mi/try");
        String ciphertext=encryptByCaeserServer.encode(front);
        modelAndView.addObject("result",ciphertext);
        return modelAndView;
    }
    //modelAndView直接插入法

    @RequestMapping("/hill")
    public String encryptionByHill(Model model,@RequestParam String front){
        String ciphertext=enByHillService.hillCode(front);
        model.addAttribute("result",ciphertext);
        return "/mi/try";
    }
    //跳轉方式

    @RequestMapping("/hill/encode")
    public String encodeHill(Model model,@RequestParam String front){
        String plaintext=enByHillService.encode(front);
        model.addAttribute("result",plaintext);
        return "/mi/try";
    }
    //@ModelAttribute方法直接讓所有的view都插入此model,此方法不講

    @RequestMapping("/playfair")
    public String encryptionByPlayfair(Model model,@RequestParam String front){
        String ciphertext=playfairerService.playfair(front);
        model.addAttribute("result",ciphertext);
        return "/mi/try";
    }

    @RequestMapping("/playfair/encode")
    public String encodePlayfair(Model model,@RequestParam String front){
        String plaintext=playfairerService.encode(front);
        model.addAttribute("result",plaintext);
        return "/mi/try";
    }

}

三個service

package com.example.dockerjd.passwordService;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.LUDecomposition;
import org.apache.commons.math3.linear.RealMatrix;
import org.springframework.stereotype.Service;

import java.util.Scanner;

/**
 * @Author: permission
 * @Description:
 * @Date: Create in 20:30 2019/10/28
 * @Modified By:
 */
@Service
public class enByHillService {

    public double[][] key={{8,6,9},{6,9,5},{5,8,4}};

    /* 作用:對三位明文加密  */
    private double[][] encrypt(double[][] b) {
        RealMatrix matrixb = new Array2DRowRealMatrix(b);
        RealMatrix matrixkey = new Array2DRowRealMatrix(key);
        double[][] matrixtoarray = matrixb.multiply(matrixkey).getData();
        return matrixtoarray;
    }

    /* 作用:字符串分割爲三位   */
    public String[] getPlaintexts(String plaintext){
        String[] plaintexts;
        if(plaintext.length()/3==0){
            plaintexts=new String[1];
        }else if(plaintext.length()%3==0){
            plaintexts=new String[plaintext.length()/3];
        }else {
            plaintexts=new String[plaintext.length()/3+1];
        }

        if(plaintext.length()>=3){
            int i=0,j=0;
            for(;i<plaintext.length()/3;i++){
                plaintexts[i]=plaintext.substring(j,j+3);
                j+=3;
            }
            if (plaintext.substring(j).length()==1){
                plaintexts[i]=plaintext.substring(j)+"xx";
            }
            if (plaintext.substring(j).length()==2){
                plaintexts[i]=plaintext.substring(j)+"x";
            }
        }else{
            if (plaintext.length()==1){
                plaintexts[0]=plaintext+"xx";
            }
            if (plaintext.length()==2){
                plaintexts[0]=plaintext+"x";
            }
        }
        return plaintexts;
    }

    /* 作用:String轉爲double【】【】   */
    public double[][] StringtoDouble(String a){
        System.out.println(a);
        char[] chars = new char[a.length()];//字符暫存數組
        for (int i = 0; i < a.length(); i++) {
            chars[i] = a.charAt(i);
        }
        double[][] b = new double[1][a.length()];//明文數組
        for (int i = 0; i < a.length(); i++) {
            int parse1=Integer.valueOf(a.charAt(i));
            b[0][i]=parse1;
        }
        return b;
    }

    /* 作用:double二維數組轉化一個字符串   */
    public  String doubleToString(double[][] array) {
        StringBuffer plaintext=new StringBuffer();
        System.out.println(array.length+"列長:"+array[0].length);
        for (int t = 0; t < array.length; t++) {
            for (int y = 0; y < array[t].length; y++) {
                int ac= (int) (array[t][y]+0.001);
                plaintext.append(ac+",");
            }
        }
        return plaintext.toString();//問題1不確定會不會出現toString變成的是一串地址嗎  沒問題
    }

    /* 作用:長加密   */
    public String hillCode(String plaintext){
        /**
         *  @Author: permission
         *  @Description: 輸入明文,即可獲得密文
         *  @Date: 2019/10/31 23:30
         *  @Param [plaintext]
         *  @Return: java.lang.String
        */
        String ciphertext="";
        double[][] ciphertexts;
        if(plaintext.length()/3==0){
            ciphertexts=new double[1][3];
        }else if(plaintext.length()%3==0){
            ciphertexts=new double[plaintext.length()/3][3];
        }else {
            ciphertexts=new double[plaintext.length()/3+1][3];
        }
        String[] plaintexts=getPlaintexts(plaintext);
        for(int i=0;i<plaintexts.length;i++){
            double[][] d=StringtoDouble(plaintexts[i]);
            double[][] d2=encrypt(d);
            ciphertexts[i]=d2[0];//i行3列,一行是一個密文串
        }
        ciphertext=doubleToString(ciphertexts);
        return ciphertext;
    }

    /* 作用:String[]數組轉化爲double[][]   */
    public double[][]  StringToDouble(String[] mingwen){
        double[][] d;
        if(mingwen.length/3==0){
            d=new double[1][3];
        }else if(mingwen.length%3==0){
            d=new double[mingwen.length/3][3];
        }else {
            d=new double[mingwen.length/3+1][3];
        }
        for(int i=0;i<d.length;i++){
            for(int j=0;j<3;j++){
                d[i][j]=Integer.valueOf(mingwen[i*3+j]);
            }
        }
        return d;
    }

    /* 作用:翻譯明文   */
    public String translate(double[][] array){
        StringBuffer plaintext=new StringBuffer();
        for (int t = 0; t < array.length; t++) {
            for (int y = 0; y < array[t].length; y++) {
                int ac= (int) (array[t][y]+0.001);
                plaintext.append((char)ac);
            }
        }
        return plaintext.toString();//問題1不確定會不會出現toString變成的是一串地址嗎  沒問題
    }

    /* 作用:對三位密文解碼   */
    public double[][] decrypt(double[][] miwen) {
        RealMatrix key_1 = inverseMatrix(new Array2DRowRealMatrix(key));
        RealMatrix matrixmiwen;
        double[][] mingwen;
        double[][] mingwens=new double[miwen.length][3];
        double[][] parse=new double[1][3];;
        for(int i=0;i<miwen.length;i++){
            parse[0]=miwen[i];
            matrixmiwen = new Array2DRowRealMatrix(parse);
            mingwen = matrixmiwen.multiply(key_1).getData();
            mingwens[i]=mingwen[0];
        }
        return mingwens;
    }

    /* 作用:長解碼   */
    public String encode(String ciphertext){
        /**
         *  @Author: permission
         *  @Description: 輸入密文,即可獲得明文
         *  @Date: 2019/10/31 23:31
         *  @Param [ciphertext]
         *  @Return: java.lang.String
        */
        String plaintext="";
        String[] ciphertexts = ciphertext.split(",");
        double[][] d=StringToDouble(ciphertexts);//String[]數組轉化爲double[][]
        double[][] mingwen=decrypt(d);//三位一組調用decrypt解密得到明文//返回的明文double[][]再次成爲我的數據結構:即i行3列的形式
        plaintext=translate(mingwen);//按順序遍歷明文double【】【】強轉爲char【】
        //char輸出爲原文。
        return plaintext;
    }

    /* 作用:key求逆   */
    public static RealMatrix inverseMatrix(RealMatrix A) {
        RealMatrix result = new LUDecomposition(A).getSolver().getInverse();
        return result;
    }
}



package com.example.dockerjd.passwordService;

import org.springframework.stereotype.Service;

/**
 * @Author: permission
 * @Description:
 * @Date: Create in 20:06 2019/10/28
 * @Modified By:
 */
@Service
public class encryptByCaeserServer {
    /* 作用:加密   */
    public String encrypt(String plaintext){
//        String fro=plaintext.substring(0,3);
//        String end=plaintext.substring(3);
//        String caeserPassword=end+fro;
        char[] chars = new char[plaintext.length()];//字符暫存數組
        for (int i = 0; i < plaintext.length(); i++) {
            chars[i] = (char)((int) plaintext.charAt(i)+3);
        }
        return new String(chars);
    }

    /* 作用:解碼   */
    public String encode(String caeserPassword){
        char[] chars = new char[caeserPassword.length()];//字符暫存數組
        for (int i = 0; i < caeserPassword.length(); i++) {
            chars[i] = (char)((int) caeserPassword.charAt(i)-3);
        }
        return new String(chars);
    }
}

package com.example.dockerjd.passwordService;

import org.springframework.stereotype.Service;

/**
 * @Author: permission
 * @Description:
 * @Date: Create in 0:07 2019/10/30
 * @Modified By:
 */
@Service
public class playfairerService {
    private char[][] key ={{'p','e','n','g','y'},
                            {'u','x','i','a','b'},
                            {'q','w','r','t','o'},
                            {'s','d','f','h','j'},
                            {'k','l','c','v','m'}};//去z版本

    /* 作用:置換   */
    private char[] change(char a,char b){
        char[] returnWord=new char[2];
        int a1=0,b1=0;
        int a2=0,b2=0;
        for(int i=0;i<5;i++){
            for (int j=0;j<5;j++){
                if(a==key[i][j]){
                    a1=i;b1=j;
                }
                if(b==key[i][j]){
                    a2=i;b2=j;
                }
            }
        }//循環遍歷,確定ij位置
        if(a1==a2){
            returnWord[0]=key[a1][(b1+1)%5];
            returnWord[1]=key[a2][(b2+1)%5];
        }else if(b1==b2){
            returnWord[0]=key[(a1+1)%5][b1];
            returnWord[1]=key[(a2+1)%5][b2];
        }else{
            returnWord[0]=key[a2][b1];
            returnWord[1]=key[a1][b2];
        }
        //比較兩個word各自的ij,if(i1=i2)那麼賦值給對應位置1/2的returnword的值是returnword【1】=key【(i+1)%5】【j】;
        //if(j1=j2),那麼對應的是rewornword【1】=key【i】【(j+1)%5】;最後,兩個if都沒有執行,那麼對應的是(交換x,而不是對x進行計算)rewornword【1】=key【i2】【j】,rewornword【1】=key【i1】【j】
        return returnWord;
    }



    /* 作用:整理明文   */
    private char[] tidyPlaintext(String plaintext){
        StringBuffer stringBuffer=new StringBuffer(plaintext);
        for(int i=0;i<stringBuffer.length();i+=2){
            if(i+1==stringBuffer.length()){//消除臨界狀態。處理數組等數據必備考慮點。
                break;
            }
            if(stringBuffer.charAt(i)==stringBuffer.charAt(i+1)){
                stringBuffer.insert(i+1,'x');//插入到指定位置,而不是指定位置後方
            }
        }
        if(stringBuffer.length()%2!=0){
            stringBuffer.append('x');
        }
        char[] returnWord=new char[stringBuffer.length()];
        for (int i = 0; i < stringBuffer.length(); i++) {
            returnWord[i] = stringBuffer.charAt(i);
        }
        return returnWord;
    }

    /* 作用:加密   */
    public String playfair(String plaintext){
        //整理明文,長度不是偶數就補上一個x,一組兩個相同就補上x。分兩步實現。最後返回字符化char【】數組,
        //二元替代函數,傳入兩個字符char【】,傳出兩個字符char【】,不夠偶數補充x
        // 存儲函數,將返回的數據循環存儲。
        String caeserPassword="";
        char[] chars=tidyPlaintext(plaintext);
        char[] parse=new char[chars.length];
        for(int i=0;i<chars.length;i+=2){//明文處理了,必定是偶數,所以不用考慮臨界基數的時候產生的越界情況
            char[] a=change(chars[i],chars[i+1]);//暫存返回結果到a
            parse[i]=a[0];parse[i+1]=a[1];//結果真正存入暫存char數組中
        }
        caeserPassword=new String(parse);
        return caeserPassword;
    }

    /* 作用:兩個char進行解碼   */
    private  char[] reBack(char a,char b ){
        char[] returnWord=new char[2];
        int a1=0,b1=0;
        int a2=0,b2=0;
        for(int i=0;i<5;i++){
            for (int j=0;j<5;j++){
                if(a==key[i][j]){
                    a1=i;b1=j;
                }
                if(b==key[i][j]){
                    a2=i;b2=j;
                }
            }
        }
        if(a1==a2){
            returnWord[0]=key[a1][(b1-1)%5];
            returnWord[1]=key[a2][(b2-1)%5];
        }else if(b1==b2){
            returnWord[0]=key[(a1+4)%5][b1];
            returnWord[1]=key[(a2+4)%5][b2];
        }else{
            returnWord[0]=key[a2][b1];
            returnWord[1]=key[a1][b2];
        }
        return returnWord;
    }
    
    /* 作用:密文處理   */
    private String tidyCiphertext(String Ciphertext){
        //沒有完善,出現了全xxx的符號,無法處理,同時,如果是3個以上的x連續,那麼,規律是每多一個x,傳入的Ciphertext就多兩個x可以利用這個規律,判定多少個連續的x,
        // 明文有3個連續x對應密文是4個x,明文4個x對應密文是6個x,密文5個對應8個x。即明文爲x 對應密文(x-2)*2+2(x>2時).

        System.out.println(Ciphertext);
        int[] a= new int[Ciphertext.length()];int j=0;//準備好表的數據結構,這裏用數組代替
        StringBuffer stringBuffer=new StringBuffer(Ciphertext);
        for(int i=1;i<stringBuffer.length();i++){//buffer遍歷,找到x並且利用數組記錄位置,將0和最後一個除外
            if(i==Ciphertext.length()-1){
                break;
            }
            else if (stringBuffer.charAt(i)=='x'){
                a[j]=i;
                j++;
            }
        }

        for(int z=0;z<j;z++){//循環對x前後判斷,一樣就刪除,不一樣就保留
            if(stringBuffer.charAt(a[z]-1)==stringBuffer.charAt(a[z]+1)){
                stringBuffer.deleteCharAt(a[z]);
                for(int k=1;k<j-z;k++){
                    a[z+k]--;
                }
            }
        }
        return stringBuffer.toString();
    }
    /* 作用:解密   */
    public String encode(String ciphered){
        if(ciphered.length()%2!=0){
            return "密文錯誤,應該是偶數密文,不要自己亂打密文";
        }
        String plaintext ="";
        char[] parse=new char[ciphered.length()];
//        char[] chars=tidyPlaintext(ciphered);//密文一定是偶數,沒有重複單詞在同一組,所以不用處理了,只要轉化爲char【】就好了
        char[] chars=tidyPlaintext(ciphered);int h=0; //準備轉換字符串的數據結構。一個表來裝,一個計數位
        for (char t:ciphered.toCharArray()
             ) {
            chars[h]=t;
            h++;
        }
        for(int i=0;i<ciphered.length();i+=2){
            char[] a=reBack(chars[i],chars[i+1]);//暫存返回結果到a
            parse[i]=a[0];parse[i+1]=a[1];//結果真正存入暫存char數組中
        }
        plaintext=new String(parse);
        return tidyCiphertext(plaintext);
    }

//    public static void main(String[] args) {
//        playfairerService playfairerService=new playfairerService();
//        String a=playfairerService.playfair("hello");
//        System.out.println(a);
//        String b=playfairerService.encode(a);
//        System.out.println(b);
//    }
}

即可實現項目。
整個項目結構源碼可以看我的github:

使用github

  1. (可選)修改git的默認打開位置:找到git bash,右鍵屬性,打開屬性如下:
    在這裏插入圖片描述
    修改目標和起始位置即可。改爲:
    在這裏插入圖片描述
    當然,也可以直接修改系統變量%HOMEDRIVE和%HOMEPATH爲你想要的路徑。
    參考:https://blog.csdn.net/qq_15971883/article/details/97916942
    參考:https://www.cnblogs.com/lightandtruth/p/9467428.html
  2. gitGUI的使用:https://jingyan.baidu.com/article/19020a0a7ae6af529c284248.html
  • 還有一篇pdf在我的github中
  1. git的一些小知識:
  • 上傳到gitlab的時候,沒有自簽名,怎麼傳送文件?
    可以通過配置:git config --global http.sslVerify false
    讓項目上傳不用密鑰,而是直接傳,如果不想改,要回到原樣,可以輸入:
 git config --global  -e

再把配置最後一個sslVerify一行刪除即可:
在這裏插入圖片描述

參考:https://www.cnblogs.com/wshiqtb/p/5160608.html
4. git一個本地倉庫推送到多個遠端:
https://blog.csdn.net/qq_36667170/article/details/79336760
5. 常見的git操作:https://www.jianshu.com/p/fb61299086b6
6. git遇到的問題:
在這裏插入圖片描述
https://blog.csdn.net/myy629464/article/details/84205258
7. git和gitlab配合使用流程:

  • 第一步是gitlab新建project
  • 在一個本地文件夾,打開git bash中建立遠端聯繫:git remote add [name] [https地址] 不用這一步,第四步已經建立聯繫了
  • git bash克隆遠端項目:git clone [https地址]
  • 進入到有.git文件的目錄,此時,遠端倉庫應該已經在.git中有了。
  • 可以正常使用了
  1. 期間遇到的bug:
  • ssh: Could not resolve hostname https: Name or service not known
    其實拉下的項目中已經有了遠端的倉庫名字,不用自己取名字,我是自己去了名字,結果還報錯說找不到
  • nothing added to commit but untracked files present
    每一次提交都需要將所有新加的文件add,不然無法提交。可以選擇將不想提交的文件添加到。ignore中就好。
  • Your branch is ahead of ‘origin/master’ by 1 commit.
    這是說遠端的版本比你的版本還要新,你若是繼續修改,後面要merge一下纔可以push。參考:https://www.liaoxuefeng.com/wiki/896043488029600/900004111093344
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章