标签归档:python

RSS feed of python

[python] ValueError: IV must be 16 bytes long

今天在研究 python 的 Crypto.Cipher 库中 AES 加密算法怎么使用,照着样例随手写了段代码,在执行时遇到以下问题:

ValueError: IV must be 16 bytes long

折腾了好一会儿都没搞定,上网看到有个大神也遇到过相同的问题,发现是在调用 AES.new 函数时参数iv 没填或不正确导致,正确的调用方法如下:

from Crypto.Cipher import AES
from Crypto import Random

key = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
mode = AES.MODE_CBC
iv = bytearray(AES.block_size)
cryptor = AES.new(key,  mode, iv)
...

或者直接把 iv 设置成

b'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'

*注意千万不要填充

b'0000000000000000'

因为其实填充的是:

import binascii
binascii.hexlify(b'0000000000000000')
'30303030303030303030303030303030'

本文链接:/2018/11/30/python-valueerror-iv-must-be-16-bytes-long/
请尊重作者的劳动成果,转载请注明出处!Sakishum 博客保留对文章的所有权利。

[Django] 将 Django 的用户认证系统登陆界面替换成 Adminlte 主题

背景简介

最近在完善之前开发的 Django 管理系统,期间有使用 Adminlte 主题替换 Django 项目中用户认证系统登陆界面默认主题,并且效果好不错,特此记录下来以供日后使用。

为了更清楚地描述步骤,所以不会引入其他第三方的库,最大限度的利用 Django 提供的基础功能。

开发前,假设 Django 已经被安装,Adminlte 已经被下载(/path/to/ adminlte)。

相关资料

  • 网站通常都会提供登录、注册、注销等用户认证功能。因此,Django 提供了一套功能完整的、灵活的、易于拓展的用户认证系统:django.contrib.auth。

  • Adminlte 是一个成熟的基于bootstrap的后台模板,下载地址

环境与版本说明

  • OS: CentOS 7
  • Python: 2.7
  • Django: 1.11.0
  • AdminLTE: 2.4.3

创建一个 Django 项目

$ django-admin startproject mysite
$ cd mysite/

修改 Django 项目中的文件

mysite/settings.py

ALLOWED_HOSTS = ['0.0.0.0',] # 修改
# ...(略过不表)...
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'),], # 修改
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
# ...(略过不表)...
# 添加以下代码
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]

LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL = '/'

mysite/views.py

# 添加以下代码
from django.shortcuts import render
from django.http import HttpResponse
from django.conf import settings
from django.contrib.auth.decorators import login_required

@login_required
def index(request):
    return render(request, 'index.html')
mysite/urls.py

from django.conf.urls import url
from django.contrib import admin
from . import views # 添加
from django.contrib.auth import views as auth_views # 添加

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', views.index, name='index'), # 添加
    url(r'^login/', auth_views.login, { 'template_name': 'login.html' }, name='login'), # 添加
    url(r'^logout/', auth_views.logout_then_login, name='logout'), # 添加
]

创建管理员(admin)用户

$ python manage.py createsuperuser
Username (leave blank to use 'username'): admin
Email address: ******
Password: ******
Password (again): 
Superuser created successfully.

引入 Adminlte 模板文件

$ mkdir templates
$ mkdir static
$ cp /path/to/AdminLTE/pages/examples/login.html templates/
$ cp /path/to/AdminLTE/pages/examples/blank.html templates/index.html
$ cp /path/to/AdminLTE/dist static/
$ cp /path/to/AdminLTE/bootstrap static/
$ cp /path/to/AdminLTE/plugins static/

修改相关 HTML 文件

template/login.html

{% load static %} <!-- 添加 -->
<!DOCTYPE html>

<!-- 以下是变更的地方 -->
<!-- Bootstrap 3.3.6 -->
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
<!-- Theme style -->
<link rel="stylesheet" href="{% static 'dist/css/AdminLTE.min.css' %}">
<!-- iCheck -->
<link rel="stylesheet" href="{% static 'plugins/iCheck/square/blue.css' %}">

<div class="login-box-body">
  {% if form.errors %} <!-- 添加 -->
    <p class="login-box-msg bg-red">Your username and password didn't match. Please try again.</p> <!-- 添加 -->
  {% else %} <!-- 添加 -->
    <p class="login-box-msg">Sign in to start your session</p>
  {% endif %} <!-- 添加 -->

<form action="{% url 'login' %}" method="post">
{% csrf_token %} <!-- 添加 -->
<input type="text" class="form-control" name="username" placeholder="Username">
<input type="password" class="form-control" name="password" placeholder="Password">

<!-- jQuery 2.2.3 -->
<script src="{% static 'plugins/jQuery/jquery-2.2.3.min.js' %}"></script>
<!-- Bootstrap 3.3.6 -->
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
<!-- iCheck -->
<script src="{% static 'plugins/iCheck/icheck.min.js' %}"></script>

template/index.html

{% load static %} <!-- 添加 -->
<!DOCTYPE html>

<!-- 以下是变更的地方 -->
<!-- Bootstrap 3.3.6 -->
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
<!-- Theme style -->
<link rel="stylesheet" href="{% static 'dist/css/AdminLTE.min.css' %}">
<!-- AdminLTE Skins. Choose a skin from the css/skins
     folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet" href="{% static 'dist/css/skins/_all-skins.min.css' %}">

<img src="{% static 'dist/img/user2-160x160.jpg' %}" class="img-circle" alt="User Image">
<img src="{% static 'dist/img/user2-160x160.jpg' %}" class="user-image" alt="User Image">
<img src="{% static 'dist/img/user2-160x160.jpg' %}" class="img-circle" alt="User Image">

<a href="{% url 'logout' %}" class="btn btn-default btn-flat">Sign out</a>

<img src="{% static 'dist/img/user2-160x160.jpg' %}" class="img-circle" alt="User Image">

<!-- jQuery 2.2.3 -->
<script src="{% static 'plugins/jQuery/jquery-2.2.3.min.js' %}"></script>
<!-- Bootstrap 3.3.6 -->
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
<!-- SlimScroll -->
<script src="{% static 'plugins/slimScroll/jquery.slimscroll.min.js' %}"></script>
<!-- FastClick -->
<script src="{% static 'plugins/fastclick/fastclick.js' %}"></script>
<!-- AdminLTE App -->
<script src="{% static 'dist/js/app.min.js' %}"></script>

目录结构

mysite/
├── manage.py
├── mysample
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── templates
│       └── index.html
├── static
│       ├── dist
│       ├── bootstrap
│       └── plugins
└── mysite
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-36.pyc
    │   └── settings.cpython-36.pyc
    ├── settings.py
    ├── urls.py
    └── wsgi.py

运行项目

$ python manage.py runserver 0.0.0.0:8080

打开浏览器并输入到“http://服务器IP:8080”,登录页面就出来了。

输入用户名“admin”和对应的密码,初始页面就会出现。

从初始画面点击“sign out”(登出),就会跳转到注销登录的页面。

以上

本文链接:/2018/07/13/django-django-adminlte/
请尊重作者的劳动成果,转载请注明出处!Sakishum 博客保留对文章的所有权利。

[Python]: 记一次使用 python 字典踩到的坑

[Python]: 记一次使用 python 字典踩到的坑

问题背景

最近在使用 python 做一个数据量很大的统计任务,抽取账号相同的记录,进行统计并排序。代码中使用到了字典,存储账号相关的记录,用账号作为键。

key = msg_id.split("_")[0]
if key  not in alerm_date_dict:
    data = nbClientData()
    data.name = key
    data.succ = cnt_succ_client
    data.fail = cnt_fail_client
    alerm_date_dict[key] = data
else:
    alerm_date_dict[key].succ += cnt_succ_client
    alerm_date_dict[key].fail += cnt_fail_client

包含以上代码的脚本跑了一个小时才把数据全部跑完,很是耗时,但是遍历数据并不应该是性能瓶颈,而且使用 python 的字典存取数据也并不慢, 但就是跑了整整一小时才跑完,是可忍孰不可忍。Stack Overflow 了一下, 原来罪魁祸首是这句代码导致的。

if key not in alerm_date_dict:

问题分析

字典是Python中唯一内建的映射类型。字典中的值并没有特殊的顺序,但是都存储在一个特点的键(key)里。键可以是数字、字符串甚至是元组。用过 python 的朋友都应该了解,判断一个 key 在不在字典或者列表里,使用 in 这个方法挺好用的。

按理说,python 的字典是C语言实现的 哈希表,效率应该不低才对。研究了一阵才发现隐藏了个坑,原来在对字典使用 in 的时候调用的是 dict.keys() 这个函数, 这个函数返回的是一个列表。

>>> newdict = {1:0, 2:0, 3:0}
>>> newdict.keys()
[1, 2, 3]

返回的列表包含了是整个字典的所有键,每次循环都返回十几万的数据,还要在列表里找对应的键,难怪那么慢!

解决办法

找到原因后,修改代码如下:

key = msg_id.split("_")[0]
if alerm_date_dict.get(key) != None:
    data = nbClientData()
    data.name = key
    data.succ = cnt_succ_client
    data.fail = cnt_fail_client
    alerm_date_dict[key] = data
else:
    alerm_date_dict[key].succ += cnt_succ_client
    alerm_date_dict[key].fail += cnt_fail_client

Python 字典(Dictionary) get() 函数返回指定键的值,如果值不在字典中返回默认值。直接操作字典,不会调用 dict.keys(),改完之后执行一两分钟就跑完任务了。

以上

本文链接:/2018/06/25/python/
请尊重作者的劳动成果,转载请注明出处!Sakishum 博客保留对文章的所有权利。

clang 实现自动脚本绑定

工作需要,实现一个自动脚本绑定的工具,因此首先要求无需手工编写任何绑定代码,此外还要考虑借助 Python 模板技术来批量生成代码,最终的目的是只需要在生成的框架上按需求添加业务逻辑。

继续阅读