go的表单验证

必填字段

Go有一个内置函数len可以获取字符串的长度,这样我们就可以通过len来获取数据的长度,例如:

if len(r.Form["username"][0])==0{
	//为空的处理
}

r.Form对不同类型的表单元素的留空有不同的处理, 对于空文本框、空文本区域以及文件上传,元素的值为空值,而如果是未选中的复选框和单选按钮,则根本不会在r.Form中产生相应条目,如果我们用上面例子中的方式去获取数据时程序就会报错。所以我们需要通过r.Form.Get()来获取值,因为如果字段不存在,通过该方式获取的是空值。但是通过r.Form.Get()只能获取单个的值,如果是map的值,必须通过上面的方式来获取。

数字

你想要确保一个表单输入框中获取的只能是数字,例如,你想通过表单获取某个人的具体年龄是50岁还是10岁,而不是像“一把年纪了”或“年轻着呢”这种描述

如果我们是判断正整数,那么我们先转化成int类型,然后进行处理

getint,err:=strconv.Atoi(r.Form.Get("age"))
if err!=nil{
	//数字转化出错了,那么可能就不是数字
}

//接下来就可以判断这个数字的大小范围了
if getint >100 {
	//太大了
}

还有一种方式就是正则匹配的方式

if m, _ := regexp.MatchString("^[0-9]+$", r.Form.Get("age")); !m {
	return false
}

对于性能要求很高的用户来说,这是一个老生常谈的问题了,他们认为应该尽量避免使用正则表达式,因为使用正则表达式的速度会比较慢。但是在目前机器性能那么强劲的情况下,对于这种简单的正则表达式效率和类型转换函数是没有什么差别的。如果你对正则表达式很熟悉,而且你在其它语言中也在使用它,那么在Go里面使用正则表达式将是一个便利的方式。

Go实现的正则是RE2,所有的字符都是UTF-8编码的。

中文

有时候我们想通过表单元素获取一个用户的中文名字,但是又为了保证获取的是正确的中文,我们需要进行验证,而不是用户随便的一些输入。对于中文我们目前有两种方式来验证,可以使用 unicode 包提供的 func Is(rangeTab *RangeTable, r rune) bool 来验证,也可以使用正则方式来验证,这里使用最简单的正则方式,如下代码所示

if m, _ := regexp.MatchString("^\\p{Han}+$", r.Form.Get("realname")); !m {
	return false
}

英文

我们期望通过表单元素获取一个英文值,例如我们想知道一个用户的英文名,应该是astaxie,而不是asta谢。

我们可以很简单的通过正则验证数据:

if m, _ := regexp.MatchString("^[a-zA-Z]+$", r.Form.Get("engname")); !m {
	return false
}

电子邮件地址

你想知道用户输入的一个Email地址是否正确,通过如下这个方式可以验证:

if m, _ := regexp.MatchString(`^([\w\.\_]{2,10})@(\w{1,}).([a-z]{2,4})$`, r.Form.Get("email")); !m {
	fmt.Println("no")
}else{
	fmt.Println("yes")
}

手机号码

你想要判断用户输入的手机号码是否正确,通过正则也可以验证:

if m, _ := regexp.MatchString(`^(1[3|4|5|8][0-9]\d{4,8})$`, r.Form.Get("mobile")); !m {
	return false
}

下拉菜单

如果我们想要判断表单里面<select>元素生成的下拉菜单中是否有被选中的项目。有些时候黑客可能会伪造这个下拉菜单不存在的值发送给你,那么如何判断这个值是否是我们预设的值呢?

我们的select可能是这样的一些元素

<select name="fruit">
<option value="apple">apple</option>
<option value="pear">pear</option>
<option value="banana">banana</option>
</select>

那么我们可以这样来验证

slice:=[]string{"apple","pear","banana"}

v := r.Form.Get("fruit")
for _, item := range slice {
	if item == v {
		return true
	}
}

return false

单选按钮

如果我们想要判断radio按钮是否有一个被选中了,我们页面的输出可能就是一个男、女性别的选择,但是也可能一个15岁大的无聊小孩,一手拿着http协议的书,另一只手通过telnet客户端向你的程序在发送请求呢,你设定的性别男值是1,女是2,他给你发送一个3,你的程序会出现异常吗?因此我们也需要像下拉菜单的判断方式类似,判断我们获取的值是我们预设的值,而不是额外的值。

<input type="radio" name="gender" value="1">男
<input type="radio" name="gender" value="2">女

那我们也可以类似下拉菜单的做法一样

slice:=[]string{"1","2"}

for _, v := range slice {
	if v == r.Form.Get("gender") {
		return true
	}
}
return false

复选框

有一项选择兴趣的复选框,你想确定用户选中的和你提供给用户选择的是同一个类型的数据。

<input type="checkbox" name="interest" value="football">足球
<input type="checkbox" name="interest" value="basketball">篮球
<input type="checkbox" name="interest" value="tennis">网球

对于复选框我们的验证和单选有点不一样,因为接收到的数据是一个slice

slice:=[]string{"football","basketball","tennis"}
a:=Slice_diff(r.Form["interest"],slice)
if a == nil{
	return true
}

return false

上面这个函数Slice_diff包含在我开源的一个库里面(操作slice和map的库),https://github.com/astaxie/beeku

日期和时间

你想确定用户填写的日期或时间是否有效。例如 ,用户在日程表中安排8月份的第45天开会,或者提供未来的某个时间作为生日。

Go里面提供了一个time的处理包,我们可以把用户的输入年月日转化成相应的时间,然后进行逻辑判断

t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
fmt.Printf("Go launched at %s\n", t.Local())

获取time之后我们就可以进行很多时间函数的操作。具体的判断就根据自己的需求调整。

身份证号码

如果我们想验证表单输入的是否是身份证,通过正则也可以方便的验证,但是身份证有15位和18位,我们两个都需要验证

//验证15位身份证,15位的是全部数字
if m, _ := regexp.MatchString(`^(\d{15})$`, r.Form.Get("usercard")); !m {
	return false
}

//验证18位身份证,18位前17位为数字,最后一位是校验位,可能为数字或字符X。
if m, _ := regexp.MatchString(`^(\d{17})([0-9]|X)$`, r.Form.Get("usercard")); !m {
	return false
}

css3 transition 和 animation实现横向、纵向 滚动、走马灯( marquee 在H5已被废弃)

css3 transition 和 animation实现横向、纵向 滚动、走马灯( marquee 在H5已被废弃)

横向:

transition写法

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>marquee</title>
<style type="text/css">
body{
padding: 0;
margin: 0;
}
#demo{
width: 100%;
height: 50px;
background: #eee;
position: fixed;
}
#demo>#spa{
word-break:keep-all;
white-space:nowrap;
position: absolute;
left: 100%;
font-size: 30px;
line-height: 50px;
}
</style>
</head>
<body>
    <div id="demo"><span id='spa' >走马灯效果</span></div>
</body>
<script type="text/javascript">
     var spa = document.getElementById("spa");
     var spaw = spa.offsetWidth;
     var bodyw = document.body.clientWidth;
     var w = 0-(spaw+bodyw);
     spa.style.transform = 'translate(' + w + 'px, 0px)';
     spa.style.transition = 'transform 5s linear';
     window.setInterval(function(){
          spa.style.transform = 'translate(0px, 0px)';
          spa.style.transition = 'transform 0s linear';
          window.setTimeout(function(){
               spa.style.transform = 'translate(' + w + 'px, 0px)';
               spa.style.transition = 'transform 5s linear';
          },100)
     },5000)
</script>
</html>

animation写法

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>marquee</title>
<style type="text/css">
#demo{
width: 100%;
height: 50px;
background: #eee;
position: fixed;
}
#demo>span{
word-break:keep-all;
white-space:nowrap;
position: absolute;
left: 100%;
font-size: 30px;
line-height: 50px;
}
#demo>.a{
-webkit-animation:demo 5s infinite;
-webkit-animation-timing-function:linear;
}
</style>
<style id='asty'></style>
</head>
<body>
    <div id="demo"><span id='spa' class='a'>走马灯效果</span></div>
</body>
<script type="text/javascript">
    var spa = document.getElementById("spa");
    var width = 0-(spa.offsetWidth);
    var style = document.getElementById("asty");
    style.innerHTML = '@-webkit-keyframes demo{from {left: 100%;}to {left: '+width+'px;}}';
    spa.className = 'a';
</script>
</html>

 

 

纵向:

一、逐条无缝滚动(无闪动)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>marquee</title>
    <style type="text/css">
        @-webkit-keyframes scrollText1 {
            0%{
                -webkit-transform: translateY(0px);
            }
            20%{
                -webkit-transform: translateY(-30px);
            }
            40%{
                -webkit-transform: translateY(-60px);
            }
            60%{
                -webkit-transform: translateY(-90px);
            }
            80%{
                -webkit-transform: translateY(-120px);
            }
            100%{
                -webkit-transform: translateY(-150px);
            }
        }

        @keyframes scrollText1 {
            0%{
                transform: translateY(0px);
            }
            20%{
                transform: translateY(-30px);
            }
            40%{
                transform: translateY(-60px);
            }
            60%{
                transform: translateY(-90px);
            }
            80%{
                transform: translateY(-120px);
            }
            100%{
                transform: translateY(-150px);
            }
        }

        .box3{
            position: relative;
            top: 20px;
            left: 20px;
            width: 200px;
            height: 30px;
            overflow: hidden;
            border:1px solid #ccc;
        }

        .border3{
            top: 0px;
            -webkit-animation:scrollText1 8s infinite  cubic-bezier(1,0,0.5,0) ;
            animation:scrollText1 8s infinite  cubic-bezier(1,0,0.5,0) ;
        }

        .border3 div{
            height: 30px;
        }

        .border3:hover{
            animation-play-state:paused;
            -webkit-animation-play-state:paused;
        }
    </style>

</head>
<body>
<div class="box3">
    <div class="border3">
        <div>This is a test 1.</div>
        <div>This is a test 2.</div>
        <div>This is a test 3.</div>
        <div>This is a test 4.</div>
        <div>This is a test 5.</div>
        <div>This is a test 1.</div>
    </div>
</div>
</body>

</html>

 

二、

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>marquee</title>
    <style type="text/css">
        .marquee div {
            display: block;
            width: 100%;
            text-align: center;
            position: absolute;
            overflow: hidden;
            -webkit-animation: marquee 5s linear infinite;
            animation: marquee 5s linear infinite;
        }
        @keyframes marquee {
            0% {
                transform: translateY(-50);
            }
            100% {
                transform: translateY(-230px); // 每行高50
            }
        }
    </style>

</head>
<body>
<div class="marquee">
    <div>
        <p class="label_txt">我是最后一个</p>
        <p>让我掉下眼泪的 不止昨夜的酒</p>
        <p>让我依依不舍的 不止你的温柔</p>
        <p>余路还要走多久 你攥着我的手</p>
        <p>走到玉林路的尽头 坐在(走过)小酒馆的门口</p>
        <p class="label_txt">我是最后一个</p>
    </div>
</div>

 

支付成功后自动跳转页面/倒计时/定时跳转页面

 

 <p>页面将在<span id="show"></span>秒后自动跳转</p>

<script type="text/javascript">
    var t=5;//设定跳转的时间
    setInterval("refer()",1000); //启动1秒定时
    function refer(){
        if(t===0){
            location="{!! url('') !!}"; //#设定跳转的链接地址

        }
        if(t>-1){
            document.getElementById('show').innerHTML=""+t+""; // 显示倒计时
            t--; // 计数器递减
        }

    }
</script>

 

Django 常用命令

创建项目

django-admin.py startproject HelloWorld

创建app
django-admin.py startapp TestModel

创建表结构
$ python manage.py migrate # 创建表结构

$ python manage.py makemigrations TestModel # 让 Django 知道我们在我们的模型有一些变更
$ python manage.py migrate TestModel # 创建表结构

在新增表后重新执行:
$ python manage.py makemigrations TestModel # 让 Django 知道我们在我们的模型有一些变更
$ python manage.py migrate TestModel # 创建表结构

python 标准数据类型

Python有五个标准的数据类型:

  • Numbers(数字)
  • String(字符串)
  • List(列表)
  • Tuple(元组)
  • Dictionary(字典)

List

列表是 Python 中使用最频繁的数据类型。

列表可以完成大多数集合类的数据结构实现。它支持字符,数字,字符串甚至可以包含列表(即嵌套)。

列表用 [ ] 标识,是 python 最通用的复合数据类型。

 l = ['A', 'b', 'C']

tuple

元组是另一个数据类型,类似于List(列表)。

元组用”()”标识。内部元素用逗号隔开。但是元组不能二次赋值,相当于只读列表。

t = ('C', 'D', 'A')

 

dict

字典(dictionary)是除列表以外python之中最灵活的内置数据结构类型。列表是有序的对象集合,字典是无序的对象集合。

两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。

字典用”{ }”标识。字典由索引(key)和它对应的值value组成。

d = {'lisa': 90, 'hanmei': 70, 'harry': 85}

 

set

set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。

>>>x = set('runoob') 
>>> y = set('google') 
>>> x, y (set(['b', 'r', 'u', 'o', 'n']), set(['e', 'o', 'g', 'l'])) # 重复的被删除 
>>> x & y # 交集 set(['o']) 
>>> x | y # 并集 set(['b', 'e', 'g', 'l', 'o', 'n', 'r', 'u']) 
>>> x - y # 差集 set(['r', 'b', 'u', 'n']) 
>>>

 

 

php rsa加密解密完整实例

<?php
/**
 * RSA加密
 * env:(PHP 4 >= 4.0.4, PHP 5, PHP 7)
 * 密钥对生成
 * 工具:OpenSSL
 * 生成私钥:genrsa -out rsa_private_key.pem 1024
 * 生成公钥:rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
 * Author:luchanglong
 * Date:2017-12-14
 * **********************************************
 * * 私钥丢失将导致数据永久无法解密
 * *********************************************
 */

header("Content-type: text/html; charset=utf-8");

class RsaTools
{
    //私钥文件路径
    private $rsaPrivateKeyFilePath;

    //私钥值
    private $rsaPrivateKey;

    //公钥文件路径
    private $rsaPublicKeyFilePath;

    //公钥值
    private $rsaPublicKey;

    function __construct()
    {
        $this->rsaPrivateKeyFilePath=dirname(__FILE__).DIRECTORY_SEPARATOR.'key'.DIRECTORY_SEPARATOR.'rsa_private_key.pem';
        $this->rsaPublicKeyFilePath=dirname(__FILE__).DIRECTORY_SEPARATOR.'key'.DIRECTORY_SEPARATOR.'rsa_public_key.pem';
    }

    /**
     *  rsa公钥加密
     **/
    public function rsaEncrypt($data) {
        if($this->checkEmpty($this->rsaPublicKeyFilePath)){
            //读取字符串
            $pubKey= $this->rsaPublicKey;
            $res = "-----BEGIN PUBLIC KEY-----\n" .
                wordwrap($pubKey, 64, "\n", true) .
                "\n-----END PUBLIC KEY-----";
        }else {
            //读取公钥文件
            $pubKey = file_get_contents($this->rsaPublicKeyFilePath);
            //转换为openssl格式密钥
            $res = openssl_get_publickey($pubKey);
        }

        ($res) or die('RSA公钥错误。请检查公钥文件格式是否正确');
        $data=trim($data);
        openssl_public_encrypt($data,$encrypted,$pubKey);//公钥加密
        $encrypted = base64_encode($encrypted);
        return $encrypted;
    }
    /**
     * rsa私钥解密
     **/
    public function rsaDecrypt($data) {

        if($this->checkEmpty($this->rsaPrivateKeyFilePath)){
            //读字符串
            $priKey=$this->rsaPrivateKey;
            $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
                wordwrap($priKey, 64, "\n", true) .
                "\n-----END RSA PRIVATE KEY-----";
        }else {
            $priKey = file_get_contents($this->rsaPrivateKeyFilePath);
            $res = openssl_get_privatekey($priKey);
        }
        ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置');
        $data=base64_decode($data);
        openssl_private_decrypt($data, $dcyCont, $res);
        return $dcyCont;
    }

    /**
     * 校验$value是否非空
     *  if not set ,return true;
     *    if is null , return true;
     **/
    protected function checkEmpty($value) {
        if (!isset($value))
            return true;
        if ($value === null)
            return true;
        if (trim($value) === "")
            return true;

        return false;
    }

}


$r=new RsaTools();
$str="0123456789?><~!@#$%^&*()_+qwertyuiopasdfghjklzxcvbnm";
echo '待加密:'.$str."<br>";
$en=$r->rsaEncrypt($str);
echo '加密后:'.$en.'<br>';
$de=$r->rsaDecrypt($en);
echo '解密后:'.$de;