Ajax+PHP+Python [利用PHP调用Python接口,实现明文加密]

1 篇文章 0 订阅
1 篇文章 0 订阅

功能:在页面上输入明文即可把加密后的密文返回到页面上,输入密文即可把明文输出到页面上。

实现思路:前台HTML页面利用Ajax异步传值到PHP处理数据,PHP将接受到的数据通过exec函数发送到Python脚本中,Python脚本处理得到的数据并将处理后的数据输出返回给PHP,PHP再将数据转换为JSON格式返回给Ajax,Ajax将得到的数据展示到HTML页面上。

环境:Nginx1.11+PHP7.2+Python3.7

1.前台HTML代码

index.html

这里使用了html + ajax 实现静态化:将所有的请求通过ajax的方式,而不是通过表单提交,a链接的方式提交,所有的接收数据也是通过ajax来接收。

表单提交数据和Ajax提交数据的区别:

1.表单提交是提交的整个页面中的数据,提交数据之后会抛弃之前的页面(刷新页面);

2.ajax是在当前页面提取某些数据并提交出去,并能接收返回来的数据,处理之后进而显示在当前页面(不刷新页面)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Enigma|加密</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

    <!-- JQuery -->
    <script src="https://code.jquery.com/jquery-3.3.1.js"></script>

    <!-- 引入vue.js -->
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

    <style>
        .box{
            width: 50%;
            margin: 20px auto;
        }
    </style>
</head>
<body>
    <div class="box" id="app">
        <form class="form-inline">
            <div class="form-group">
              <label for="exampleInputName2">{{message}}</label>
              <input type="text" name="password" class="form-control" id="exampleInputName2" placeholder="明文/密文">
            </div>
            <div class="form-group">
              <!-- <label for="exampleInputEmail2">加密/解密</label> -->
              <input type="text" class="form-control" id="exampleInputEmail2">
            </div>
            <!-- 不能使用submit,会刷新整个页面 -->
            <button type="button" id="btn" class="btn btn-default">加密/解密</button>
            <span id="con"></span>
          </form>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                message: '明文/密文'
            }
        });
        // 发送ajax
        $("#btn").bind("click",function(){
            var password=$("input[name=password]").val();
            if(password==""||password==null){
                alert("明文/密文不能为空!");
                return false;
            }else{
                // 发送ajax请求
                $.ajax({
                    type:'POST',
                    dataType:"json",
                    url:'index.php',
                    data:{"password":password},
                    async:false,
                    success:function(data,status){
                        // 如果调用PHP成功
                        // alert(status);
                        // alert(data);
                        $('#exampleInputEmail2').val(data[0]);
                    },
                });
            }
        });
    </script>
</body>
</html>

2.后台PHP代码

index.php

这里用passthru()和exec()发送数据的区别的区别

1.passthru():允许运行外部程序,并在屏幕上显示结果。不需要使用 echo 或 return 来查看结果,它会将输出结果直接输出到浏览器(或当前终端)。可以添加可选的参数,即保存从外部程序返回的代码的变量,比如表示成功的 0,这为调试提供更好的机制。

2.exec():它返回输出的最后一行,并且可选地用命令的完整输出和错误代码填充数组。

<?php
/**
 * 接收POST传值,然后传参到Python脚本
 * @param $params 接收到的ajax传值
 */
if($_POST){
    $params = $_POST['password']; #传递给python脚本的入口参数 
    // 判断是否接收到数据
    if($params!=''){
        // 发送数据到python脚本
        $path="python Enigma.py "; //需要注意的是:末尾要加一个空格
        // passthru($path.$params);//等同于命令`python python.py 参数`,并接收打印出来的信息--->直接输出python打印的结果
        exec($path.$params,$data);//返回的$data为一个数组
        echo json_encode($data);// 返回给ajax一个json数据
    }else{
        echo ('请输入明文或密文!');
    }
}

3.后台Python代码

Enigma.py

这部分Python代码来自博客:PYTHON编程挑战——恩格玛机完成版!,感谢博主的分享。

我在这修改部分代码:

1.使输出结果在网页上不会是乱码,主要是中文;

2.使整个程序不会陷入死循环中。

# -*- coding:utf-8 -*-
# 本代码的目的是通过python实现德军二战时期的密码机:恩格玛
import re
import string
# 接收PHP传的参数
import sys
# 网页中文显示
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
 
def simple_replace(password, replace_word1, replace_word2, replace_word3):  # 加密的主函数
    count = 0  # 设置计数器
    new_pass = ''  # 设置一个空字符串准备接收密码
    ori_table = 'abcdefghijklmnopqrstuvwxyz'  # 原始的字符串,用来建立映射表
    for obj in password:  # 开始拆解原字符串
        table1 = str.maketrans(ori_table, replace_word1)  # 建立转子1的映射表
        table2 = str.maketrans(ori_table, replace_word2)  # 建立转子2的映射表
        table3 = str.maketrans(ori_table, replace_word3)  # 建立转子3的映射表
        new_obj = str.translate(obj, table1)  # 把obj通过转子1转换
        new_obj = str.translate(new_obj, table2)  # obj通过转子2
        new_obj = str.translate(new_obj, table3)  # obj通过转子3
        new_obj = reverse_word(new_obj)  # 进入自反器,得到自反值
        reverse_table1 = str.maketrans(replace_word1, ori_table)  # 增加自反出去的对应表,反向解译
        reverse_table2 = str.maketrans(replace_word2, ori_table)
        reverse_table3 = str.maketrans(replace_word3, ori_table)
        new_obj = str.translate(new_obj, reverse_table3)  # new_obj再赋值,反向解译通过转子3
        new_obj = str.translate(new_obj, reverse_table2)  # 通过转子2
        new_obj = str.translate(new_obj, reverse_table1)  # 通过转子1
        new_pass += new_obj  # 返回的密码增加一个new_obj
        replace_word1 = rotors(replace_word1)  # 转子1每个字符都转动一次
        count += 1  # 计数器增加1
        if count % 676 == 0:   # 如果模676为0,那么转子3转动一次(因为转子2已经转动了一整圈)
            replace_word3 = rotors(replace_word3)
        elif count % 26 == 0:  # 如果模26为0,那么转子2转动一次(因为转子1已经转动了一整圈)
            replace_word2 = rotors(replace_word2)
    return new_pass  # 返回新的已经被转子加密的密码
 
# 单独把判断写成一个函数吧,这样比较好区分
 
 
def is_str(password, replace_word1, replace_word2, replace_word3):  # 判断的函数
    an = re.match('[a-z]+$', password)  # 当时的enigma机是没有空格的,所以这里要求输入的明文也必须是小写字母
    if not type(password) == type(replace_word1) == type(replace_word2) == type(replace_word3) == type('a'):
        print('密码必须是字符串!')
        return False
    elif not an:
        print('字符串只能包含小写字母!')
        return False
    elif not len(replace_word1) == len(replace_word2) == len(replace_word3) == 26:
        print('替换码必须为26个字母!')
        return False
    else:
        return True  # 修正了函数的写法,增加了一个返回true的选项
 
 
def rotors(replace_word):  # 转子转动的函数,每调用一次,就把转子前面第一个字母移动到最后
    return replace_word[1:] + replace_word[0]
 
# 还没有自反器呢!加密之后无法解密,是何其的蛋疼!
# 自反器很好设置的,只要设置一个字典,保证所有字母(26个)两两对应就可以了,怎么对应,你说了算!
 
 
def reverse_word(word):
    dic = {'a': 'n', 'b': 'o', 'c': 'p', 'd': 'q',
           'e': 'r', 'f': 's', 'g': 't', 'h': 'u',
           'i': 'v', 'j': 'w', 'k': 'x', 'l': 'y',
           'm': 'z', 'n': 'a', 'o': 'b', 'p': 'c',
           'q': 'd', 'r': 'e', 's': 'f', 't': 'g',
           'u': 'h', 'v': 'i', 'w': 'j', 'x': 'k',
           'y': 'l', 'z': 'm'}
    return dic[word]

while True:
    # a_password = input('请输入明文加密或密文解密:')
    a_password  = sys.argv[1]
    r_password1 = 'qwertyuiopasdfghjklzxcvbnm'  # 转子1,自己设置即可
    r_password2 = 'asdfqwerzxcvtyuiopghjklbnm'  # 转子2,自己设置即可
    r_password3 = 'poiuytrewqasdfghjklmnbvcxz'  # 转子3,自己设置即可
    if is_str(a_password, r_password1, r_password2, r_password3):
        print('密文/明文如下:', simple_replace(a_password, r_password1, r_password2, r_password3))
        break   # 输出一次后跳出循环,避免进入死循环
    else:
        break   # 输出一次后跳出循环,避免进入死循环

结果展示

初始页面:

明文加密:

密文解密:

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值