python实现AES加密解密


Posted in Python onMarch 28, 2019

本文实例为大家分享了python实现AES加密解密的具体代码,供大家参考,具体内容如下

(1)对于AES加密解密相关知识

(2)实现的功能就是输入0-16个字符,然后经过AES的加密解密最后可以得到原先的输入,运行的结果如下

python实现AES加密解密

开始的字符串就是输入的明文,第一个矩阵,是明文对应的状态矩阵,下面的字典是得到的经过扩展后的密钥,再下面的矩阵是经过加密之后的矩阵,最后的矩阵就是解密之后的矩阵,最后的输出就是还原的明文,可以发现AES加密解密的过程没毛病。

(3)字节代换:输入输出都是十六进制的矩阵格式,define_byte_subdtitution()函数的功能是完成字节代换,首先使用hex_to_int_number()函数将十六进制数转换为对应的十进制数,然后到S盒与逆S盒中进行字节的代换,这个过程中比较麻烦的是S盒与逆S盒数据的输入,好家伙。而逆字节代换就是使用逆S盒;

(4)行移位:输入输出都是十六进制的矩阵格式,define_line_shift()函数是在加密时使用的,define_line_inverse_shift()函数是在解密时使用的;

(5)列混合:输入是使用的十进制矩阵,输出是十六进制的矩阵,在列混合前为了方便操作,使用函数define_column_rotation()将矩阵进行了行列交换位置,然后对每一个数据进行操作,get_2()函数是实现与2相乘的结果,在加密与解密中会多次用到,XOR()函数实现两个二进制数的异或操作,在逆列混合中就是左乘的矩阵有所不同;

(6)轮密钥加:输入输出都是十六进制的矩阵格式,在进行加密解密之前先将密钥进行扩展,得到加解密过程中使用的所有的密钥,并放在一个字典中,然后在加密解密过程中使用相应的密钥即可,get_extend_key()函数得到扩展密钥,一共有44个字,每次在进行轮密钥加时使用4个字,get_round_key_plus()函数实现轮密钥加的操作,就是进行异或操作;

(7)最后就是实现加密与解密的详细的过程,其中的九轮是一样的,最后一轮单独拿出来进行处理即可,主要的问题可能会出现在一些小细节的处理上,像我遇到的就是在解密中控制使用轮密钥的变量k,开始把k放在了10轮循环中,导致k的值一直是初值没有改变,所以加密解密没有成功,之后我就在各个步骤中一个一个的测试,发现字节代换,行移位,列混合,甚至轮密钥加单独使用的时候都可以实现还原明文,然后,我又仔细的检查了下,加密解密的函数,终于发现了这个问题,问题虽小,但是影响很大,使得整个的程序没有得到预想的结果,幸好最后的结局还算满意,就是写的代码有点乱,自己也懒得改了,希望有大佬要是有什么意见,可以随时交流。

import random
 
def get_matrix_of_clear_number(clear_number):
 #得到输入数据对应的十六进制ASCII码矩阵
 dir = {0:[], 1:[], 2:[], 3:[]}
 length = len(clear_number)
 for i in range(length):
 number = ord(clear_number[i])
 dir[i % 4].append(hex(number))
 return dir
 
def get_matrix_of_cipher_number():
 #得到随机生成的密钥的十六进制矩阵 
 dir_number = {10:"A", 11:"B", 12:"C", 13:"D", 14:"E", 15:"F"}
 string = ''
 for i in range(16):
 number = int(random.random() * 16)
 if(number >= 10):
  number = dir_number[number]
 else:
  number = str(number)
 string = string + number
 
 dir = get_matrix_of_clear_number(string)
 return dir
 
def define_S_box(fir_num, last_num):
 #定义S盒
 dir = {
 0:['0x63', '0x7c', '0x77', '0x7b', '0xf2', '0x6b', '0x6f', '0xc5', '0x30', '0x01', '0x67', '0x2b', 
 '0xfe', '0xd7', '0xab', '0x76'],
 1:['0xca', '0x82', '0xc9', '0x7d', '0xfa', '0x59', '0x47', '0xf0', '0xad', '0xd4', '0xa2', '0xaf', '0x9c', '0xa4', '0x72', '0xc0'],
 2:['0xb7', '0xfd', '0x93', '0x26', '0x36', '0x3f', '0xf7', '0xcc', '0x34', '0xa5', '0xe5', '0xf1',  '0x71', '0xd8', '0x31', '0x15'],
 3:['0x04', '0xc7', '0x23', '0xc3', '0x18', '0x96', '0x05', '0x9a', '0x07', '0x12', '0x80', '0xe2', '0xeb', '0x27', '0xb2', '0x75'],
 4:['0x09', '0x83', '0x2c', '0x1a', '0x1b', '0x6e', '0x5a', '0xa0', '0x52', '0x3b', '0xd6', '0xb3', '0x29', '0xe3', '0x2f', '0x84'],
 5:['0x53', '0xd1', '0x00', '0xed', '0x20', '0xfc', '0xb1', '0x5b', '0x6a', '0xcb', '0xbe', '0x39', '0x4a', '0x4c', '0x58', '0xcf'],
 6:['0xd0', '0xef', '0xaa', '0xfb', '0x43', '0x4d', '0x33', '0x85', '0x45', '0xf9', '0x02', '0x7f', 
 '0x50', '0x3c', '0x9f', '0xa8'],
 7:['0x51', '0xa3', '0x40', '0x8f', '0x92', '0x9d', '0x38', '0xf5', '0xbc', '0xb6', '0xda', '0x21', 
 '0x10', '0xff', '0xf3', '0xd2'],
 8:['0xcd', '0x0c', '0x13', '0xec', '0x5f', '0x97', '0x44', '0x17', '0xc4', '0xa7', '0x7e', '0x3d', 
 '0x64', '0x5d', '0x19', '0x73'],
 9:['0x60', '0x81', '0x4f', '0xdc', '0x22', '0x2a', '0x90', '0x88', '0x46', '0xee', '0xb8', '0x14', 
 '0xde', '0x5e', '0x0b', '0xdb'],
 10:['0xe0', '0x32', '0x3a', '0x0a', '0x49', '0x06', '0x24', '0x5c', '0xc2', '0xd3', '0xac', '0x62', '0x91', '0x95', '0xe4', '0x79'],
 11:['0xe7', '0xc8', '0x37', '0x6d', '0x8d', '0xd5', '0x4e', '0xa9', '0x6c', '0x56', '0xf4', '0xea', '0x65', '0x7a', '0xae', '0x08'],
 12:['0xba', '0x78', '0x25', '0x2e', '0x1c', '0xa6', '0xb4', '0xc6', '0xe8', '0xdd', '0x74', '0x1f', '0x4b', '0xbd', '0x8b', '0x8a'],
 13:['0x70', '0x3e', '0xb5', '0x66', '0x48', '0x03', '0xf6', '0x0e', '0x61', '0x35', '0x57', '0xb9', '0x86', '0xc1', '0x1d', '0x9e'],
 14:['0xe1', '0xf8', '0x98', '0x11', '0x69', '0xd9', '0x8e', '0x94', '0x9b', '0x1e', '0x87', '0xe9', '0xce', '0x55', '0x28', '0xdf'],
 15:['0x8c', '0xa1', '0x89', '0x0d', '0xbf', '0xe6', '0x42', '0x68', '0x41', '0x99', '0x2d', '0x0f', '0xb0', '0x54', '0xbb', '0x16']
 } 
 return (dir[fir_num][last_num])
 
def define_inverse_S_box(fir_num, last_num):
 #定义S逆盒
 dir = {
 0:['0x52', '0x09', '0x6a', '0xd5', '0x30', '0x36', '0xa5', '0x38', '0xbf', '0x40', '0xa3', '0x9e', '0x81', '0xf3', '0xd7', '0xfb'],
 1:['0x7c', '0xe3', '0x39', '0x82', '0x9b', '0x2f', '0xff', '0x87', '0x34', '0x8e', '0x43', '0x44', '0xc4', '0xde', '0xe9', '0xcb'],
 2:['0x54', '0x7b', '0x94', '0x32', '0xa6', '0xc2', '0x23', '0x3d', '0xee', '0x4c', '0x95', '0x0b', '0x42', '0xfa', '0xc3', '0x4e'],
 3:['0x08', '0x2e', '0xa1', '0x66', '0x28', '0xd9', '0x24', '0xb2', '0x76', '0x5b', '0xa2', '0x49', '0x6d', '0x8b', '0xd1', '0x25'],
 4:['0x72', '0xf8', '0xf6', '0x64', '0x86', '0x68', '0x98', '0x16', '0xd4', '0xa4', '0x5c', '0xcc', '0x5d', '0x65', '0xb6', '0x92'],
 5:['0x6c', '0x70', '0x48', '0x50', '0xfd', '0xed', '0xb9', '0xda', '0x5e', '0x15', '0x46', '0x57', '0xa7', '0x8d', '0x9d', '0x84'],
 6:['0x90', '0xd8', '0xab', '0x00', '0x8c', '0xbc', '0xd3', '0x0a', '0xf7', '0xe4', '0x58', '0x05', '0xb8', '0xb3', '0x45', '0x06'],
 7:['0xd0', '0x2c', '0x1e', '0x8f', '0xca', '0x3f', '0x0f', '0x02', '0xc1', '0xaf', '0xbd', '0x03', '0x01', '0x13', '0x8a', '0x6b'],
 8:['0x3a', '0x91', '0x11', '0x41', '0x4f', '0x67', '0xdc', '0xea', '0x97', '0xf2', '0xcf', '0xce', '0xf0', '0xb4', '0xe6', '0x73'],
 9:['0x96', '0xac', '0x74', '0x22', '0xe7', '0xad', '0x35', '0x85', '0xe2', '0xf9', '0x37', '0xe8', '0x1c', '0x75', '0xdf', '0x6e'],
 10:['0x47', '0xf1', '0x1a', '0x71', '0x1d', '0x29', '0xc5', '0x89', '0x6f', '0xb7', '0x62', '0x0e', '0xaa', '0x18', '0xbe', '0x1b'],
 11:['0xfc', '0x56', '0x3e', '0x4b', '0xc6', '0xd2', '0x79', '0x20', '0x9a', '0xdb', '0xc0', '0xfe', '0x78', '0xcd', '0x5a', '0xf4'],
 12:['0x1f', '0xdd', '0xa8', '0x33', '0x88', '0x07', '0xc7', '0x31', '0xb1', '0x12', '0x10', '0x59', '0x27', '0x80', '0xec', '0x5f'],
 13:['0x60', '0x51', '0x7f', '0xa9', '0x19', '0xb5', '0x4a', '0x0d', '0x2d', '0xe5', '0x7a', '0x9f', '0x93', '0xc9', '0x9c', '0xef'],
 14:['0xa0', '0xe0', '0x3b', '0x4d', '0xae', '0x2a', '0xf5', '0xb0', '0xc8', '0xeb', '0xbb', '0x3c', '0x83', '0x53', '0x99', '0x61'],
 15:['0x17', '0x2b', '0x04', '0x7e', '0xba', '0x77', '0xd6', '0x26', '0xe1', '0x69', '0x14', '0x63', '0x55', '0x21', '0x0c', '0x7d']
 
 } 
 return (dir[fir_num][last_num])
 
def hex_to_int_number(hex_num, flag):
 #十六进制矩阵转换为十进制矩阵
 number = int(hex_num, 16)
 int_num = number // 16
 int_re = number % 16
 if flag == 1:
 my_number = define_S_box(int_num, int_re)
 else:
 my_number = define_inverse_S_box(int_num, int_re)
 return my_number 
 
def define_byte_subdtitution(dir_new_number, flag):
 #定义字节代换
 dir_1 = {0:[], 1:[], 2:[], 3:[]}
 for j in range(4):
 list_new = []
 list = dir_new_number[j]
 for k in range(4): 
  new_num = hex_to_int_number(list[k], flag)
  list_new.append(new_num)
 dir_1[j] = list_new
 return dir_1
 
 
def define_line_shift(dir_clear_number):
 #进行行移位操作
 for i in range(4):
 my_list = []
 list = dir_clear_number[i]
 for j in range(4):
  my_list.append(list[(j + i) % 4])
 dir_clear_number[i] = my_list
 return dir_clear_number
 
def define_line_inverse_shift(dir_clear_number):
 #进行行移位的逆操作
 for i in range(4):
 my_list = []
 list = dir_clear_number[i]
 for j in range(4):
  my_list.append(list[(j + 4 - i) % 4])
 dir_clear_number[i] = my_list
 return dir_clear_number
 
 
def XOR(string_1, string_2):
 #得到异或后的十进制结果 
 decimal_result = 0
 for i in range(8):
 if string_1[i] != string_2[i]:
  decimal_result += 2 ** (7 - i)
 
 return decimal_result
 
def dex_to_int(string):
 #得到数据二进制到十进制的转换
 my_result = 0
 for k in range(8): 
 if string[k] == '1':
  my_result += 2 ** (7 - k)
 return my_result 
  
def get_2(last_num):
 #得到列混合中乘以2的结果 
 last_num_copy = last_num
 last_num_copy = bin(last_num_copy)[2:].rjust(8, '0')
 judge_num = bin(last_num)[2:] 
 judge_num = last_num_copy[0]
 last_num_copy = last_num_copy[1:]
 last_num_copy += '0'
 
 if judge_num == '1':
 string_judge = '00011011' 
 last_num_copy = bin(XOR(string_judge, last_num_copy))[2:].rjust(8, '0') 
 return last_num_copy
 
def define_column_rotation(dir_clear_number_copy):
 #在列混合中先将列进行旋转
 dir_clear_number = {0:[], 1:[], 2:[], 3:[]}
 for key, num in dir_clear_number_copy.items():
 list = num 
 for i in range(4):
  dir_clear_number[i].append(list[i]) 
 return dir_clear_number
 
def define_column_hybrid(dir_clear_number_copy):
 #进行列混合操作,得到对应的十六进制的矩阵 
 dir_matrix = {
 0:[2, 3, 1, 1],
 1:[1, 2, 3, 1],
 2:[1, 1, 2, 3],
 3:[3, 1, 1, 2]
 }
 dir_clear_number = define_column_rotation(dir_clear_number_copy) 
 dir_new_clear_number = {0:[], 1:[], 2:[], 3:[]}
 
 for i in range(4): 
 list_matrix = dir_matrix[i]
 list = []
 for j in range(4): 
  list_num = dir_clear_number[j] 
  string = '' 
  my_string = '00000000'
 
  for k in range(4):
  if list_matrix[k] == 2:
   string = get_2(list_num[k])
  if list_matrix[k] == 3:
   string = get_2(list_num[k])
   list_num_copy = bin(list_num[k])[2:].rjust(8, '0')
   string = bin(XOR(string, list_num_copy))[2:].rjust(8, '0')
  if list_matrix[k] == 1:
   string = bin(list_num[k])[2:].rjust(8, '0') 
  my_string = bin(XOR(my_string, string))[2:].rjust(8, '0')
  my_result = dex_to_int(my_string)
  list.append(hex(my_result))
  dir_new_clear_number[i] = list
 return dir_new_clear_number
 
def define_inverse_column_hybrid(dir_clear_number_copy):
 #进行列混合逆操作,得到对应的十六进制的矩阵 
 dir_matrix = {
 0:[14, 11, 13, 9],
 1:[9, 14, 11, 13],
 2:[13, 9, 14, 11],
 3:[11, 13, 9, 14]
 }
 dir_clear_number = define_column_rotation(dir_clear_number_copy)
 
 dir_new_clear_number = {0:[], 1:[], 2:[], 3:[]}
 for i in range(4): 
 list_matrix = dir_matrix[i]
 list = []
 for j in range(4): 
  list_num = dir_clear_number[j] 
  string = '' 
  my_string = '00000000'
  my_result = 0 
   
  for k in range(4):
  if list_matrix[k] == 14:
   string_1 = get_2(list_num[k])
   string_1_int = dex_to_int(string_1)
   string_2 = get_2(string_1_int)
   string_2_int = dex_to_int(string_2)
   string_3 = get_2(string_2_int)
   string = bin(XOR(string_2, string_1))[2:].rjust(8, '0')
   string = bin(XOR(string, string_3))[2:].rjust(8, '0')
  if list_matrix[k] == 11:
   string_1 = get_2(list_num[k])
   string_1_int = dex_to_int(string_1)
   string_2 = get_2(string_1_int)
   string_2_int = dex_to_int(string_2)
   string_3 = get_2(string_2_int)
   
   string_4 = bin(list_num[k])[2:].rjust(8, '0') 
   string = bin(XOR(string_3, string_1))[2:].rjust(8, '0')
   string = bin(XOR(string, string_4))[2:].rjust(8, '0')
   
  if list_matrix[k] == 13:
   string_1 = get_2(list_num[k])
   string_1_int = dex_to_int(string_1)
   string_2 = get_2(string_1_int)
   string_2_int = dex_to_int(string_2)
   string_3 = get_2(string_2_int)
   
   string_4 = bin(list_num[k])[2:].rjust(8, '0') 
   string = bin(XOR(string_3, string_2))[2:].rjust(8, '0')
   string = bin(XOR(string, string_4))[2:].rjust(8, '0')
  if list_matrix[k] == 9:
   string_1 = get_2(list_num[k])
   string_1_int = dex_to_int(string_1)
   string_2 = get_2(string_1_int)
   string_2_int = dex_to_int(string_2)
   string_3 = get_2(string_2_int)
   
   string_4 = bin(list_num[k])[2:].rjust(8, '0')
   string = bin(XOR(string_3, string_4))[2:].rjust(8, '0')
 
  my_string = bin(XOR(my_string, string))[2:].rjust(8, '0')
 
  my_result = dex_to_int(my_string)
  list.append(hex(my_result))
  dir_new_clear_number[i] = list
 return dir_new_clear_number
 
def hex_to_int(dir_clear_number):
 #将十六进制的矩阵转换为十进制的矩阵
 dir_clear_number_copy = {0:[], 1:[], 2:[], 3:[]}
 for key, num in dir_clear_number.items():
 list = []
 for i in range(4):
  list.append(int(num[i], 16))
 dir_clear_number_copy[key] = list 
 return dir_clear_number_copy
 
def get_4_double(i_num, num, dir_key):
 #在轮密钥加中 ,得到4的倍数
 dir_R = {
 1: ['01','00', '00', '00'],
 2: ['02', '00', '00', '00'],
 3: ['04', '00', '00', '00'],
 4: ['08', '00', '00', '00'],
 5: ['10', '00', '00', '00'],
 6: ['20', '00', '00', '00'],
 7: ['40', '00', '00', '00'],
 8: ['80', '00', '00', '00'],
 9: ['1B', '00', '00', '00'],
 10: ['36', '00', '00', '00']
 }
 list_R = dir_R[i_num // 4 + 1] 
 list = []
 list_dir = dir_key[num - 1]
 #print(list_dir)
 for i in range(4):
 list.append(list_dir[(i + 1) % 4])
 
 for i in range(4): 
 list_int = int(list[i], 16)
 line_number = list_int // 16
 row_number = list_int % 16 
 
 list[i] = define_S_box(line_number, row_number)
 list_new = []
 for i in range(4): 
 num_1 = int(list_R[i], 16)
 num_2 = int(list[i], 16)
 string_1 = bin(num_1)[2:].rjust(8, '0')
 string_2 = bin(num_2)[2:].rjust(8, '0')
 string = XOR(string_1, string_2)
 list_new.append(hex(string))
 return list_new
 
def get_extend_key(dir_cipher_number):
 #得到扩展密钥
 dir_cipher_number_copy = dir_cipher_number
 
 dir_key = {}
 for i in range(44):
 dir_key[i] = []
 
 for j in range(4):
 list = []
 list_dir = dir_cipher_number_copy[j]
 for k in range(4):
  list.append(list_dir[k])
 dir_key[j] = list
 
 for i in range(40):
 num = 4 + i
 if num % 4 == 0:
  list_T = get_4_double(i, num, dir_key)
 else:
  list_T = dir_key[num - 1]
 
 list_key = dir_key[num - 4]
 list = []
 for j in range(4):
  string_1 = bin(int(list_T[j], 16))[2:].rjust(8, '0')
  string_2 = bin(int(list_key[j], 16))[2:].rjust(8, '0')
  string = XOR(string_1, string_2)
  list.append(hex(string))
 dir_key[4 + i] = list
 return dir_key
 
def get_round_key_plus(clear_number, dir_key_extend):
 #进行轮密钥加的操作
 dir_new_number = {0:[], 1:[], 2:[], 3:[]}
 for i in range(4):
 list_number = clear_number[i]
 list_key = dir_key_extend[i]
 list = []
 for j in range(4):
  number = int(list_number[j], 16)
  key = int(list_key[j], 16)
  string_num = bin(number)[2:].rjust(8, '0')
  string_key = bin(key)[2:].rjust(8, '0')
  result_int = XOR(string_num, string_key)
  list.append(hex(result_int))
 dir_new_number[i] = list
 return dir_new_number
 
def define_encryption(clear_number, dir_key_extend):
 #对明文进行轮密钥加
 dir_new_number = get_round_key_plus(clear_number, dir_key_extend)
 
 #进行中间的十轮运算
 for i in range(10): 
 num = 4 * (i + 1)
 dir_key_extend_part = {}
 
 for j in range(4):
  dir_key_extend_part[j] = dir_key_extend[num]
  num += 1
 
 #字节代换
 dir_1 = define_byte_subdtitution(dir_new_number, 1)
 
 #行移位
 dir_1 = define_line_shift(dir_1)
 
 #定义列混合操作
 if i != 9:
  dir_1 = hex_to_int(dir_1)
  dir_1 = define_column_hybrid(dir_1)
 
 #定义轮密钥加
 dir_1 = get_round_key_plus(dir_1, dir_key_extend_part)
 dir_new_number = dir_1
 
 return dir_new_number
 
def define_decryption(clear_number, dir_key_extend):
 #对密文进行轮密钥加
 dir_key_extend_part = {
  0: dir_key_extend[40],
  1: dir_key_extend[41],
  2: dir_key_extend[42],
  3: dir_key_extend[43]
  }
 dir_new_number = get_round_key_plus(clear_number, dir_key_extend_part)
 
 #进行中间的十轮运算
 k = 9
 for i in range(10):  
 num = 4 * k
 dir_key_extend_part = {}
 for j in range(4):
  dir_key_extend_part[j] = dir_key_extend[num]
  num += 1
 k -= 1
 
 #逆行移位
 dir_1 = define_line_inverse_shift(dir_new_number)
 
 #逆字节代换
 dir_1 = define_byte_subdtitution(dir_1, 0)
  
 #定义轮密钥加
 dir_1 = get_round_key_plus(dir_1, dir_key_extend_part)
 dir_new_number = dir_1
 
 #定义逆列混合操作
 if i != 9:
  dir_1 = hex_to_int(dir_1)
  dir_1 = define_inverse_column_hybrid(dir_1)
 dir_new_number = dir_1
 return dir_new_number
 
def print_(dir_num):
 #测试输出字典
 for key, num in dir_num.items():
 print(num)
 
def get_outcome(dir_num):
 #输出解密之后的内容
 dir_num = define_column_rotation(dir_num)
 string = ''
 for i in range(4):
 list_num = dir_num[i]
 for j in range(4):
  num = list_num[j]
  num = chr(int(num, 16))
  string += num
 return string 
 
def get_standard_input(string):
 #得到16个字符的输入
 length = len(string)
 length = 16 - length
 for i in range(length):
 string += '0'
 return string 
 
if __name__ == "__main__":
 print("Enter numbers( 0 - 16 number, if less than 16, it will fill with '0' by default): ")
 clear_number = input()
 clear_number = get_standard_input(clear_number)
 
 #得到明文矩阵
 dir_clear_number = get_matrix_of_clear_number(clear_number)
 
 print_(dir_clear_number) #输出明文矩阵
 print("\n")
 
 #得到密文矩阵
 dir_cipher_number = get_matrix_of_cipher_number()
 
 #得到扩展的密钥
 dir_key_extend = get_extend_key(dir_cipher_number)
 
 print(dir_key_extend) #输出扩展密钥
 print("\n")
 
 dir_new_encrypt_number = define_encryption(dir_clear_number, dir_key_extend)
 print_(dir_new_encrypt_number) #输出密文矩阵
 print("\n")
 
 dir_orinal_ = define_decryption(dir_new_encrypt_number, dir_key_extend)
 print_(dir_orinal_) #输出解密后的矩阵
 
 dir_ = get_outcome(dir_orinal_)
 print(dir_) #输出解密后的原文

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现利用最大公约数求三个正整数的最小公倍数示例
Sep 30 Python
机器学习python实战之手写数字识别
Nov 01 Python
python opencv 直方图反向投影的方法
Feb 24 Python
用Python分析3天破10亿的《我不是药神》到底神在哪?
Jul 12 Python
对django 模型 unique together的示例讲解
Aug 06 Python
Django实现发送邮件找回密码功能
Aug 12 Python
Python从文件中读取指定的行以及在文件指定位置写入
Sep 06 Python
Python列表list常用内建函数实例小结
Oct 22 Python
浅谈Python3多线程之间的执行顺序问题
May 02 Python
基于python实现matlab filter函数过程详解
Jun 08 Python
零基础学python应该从哪里入手
Aug 11 Python
python中函数返回多个结果的实例方法
Dec 16 Python
详解python tkinter教程-事件绑定
Mar 28 #Python
Python中捕获键盘的方式详解
Mar 28 #Python
python sort、sort_index方法代码实例
Mar 28 #Python
详解python selenium 爬取网易云音乐歌单名
Mar 28 #Python
pyqt5利用pyqtDesigner实现登录界面
Mar 28 #Python
Django实现单用户登录的方法示例
Mar 28 #Python
pyqt5实现登录界面的模板
May 30 #Python
You might like
通过修改Laravel Auth使用salt和password进行认证用户详解
2017/08/17 PHP
jquery+json 通用三级联动下拉列表
2010/04/19 Javascript
JavaScript中使用replace结合正则实现replaceAll的效果
2010/06/04 Javascript
jquery ajax return没有返回值的解决方法
2011/10/20 Javascript
Ext JS 4官方文档之三 -- 类体系概述与实践
2012/12/16 Javascript
一个背景云变换js特效 鼠标移动背景云变化
2012/12/28 Javascript
JS小功能(offsetLeft实现图片滚动效果)实例代码
2013/11/28 Javascript
Javascript 完美运动框架(逐行分析代码,让你轻松了运动的原理)
2015/01/23 Javascript
jQuery+PHP实现微信转盘抽奖功能的方法
2016/05/25 Javascript
AngularJS 过滤与排序详解及实例代码
2016/09/14 Javascript
深入理解Node.js的HTTP模块
2016/10/12 Javascript
Jquery Easyui搜索框组件SearchBox使用详解(19)
2016/12/17 Javascript
ionic2打包android时gradle无法下载的解决方法
2017/04/05 Javascript
angular2中router路由跳转navigate的使用与刷新页面问题详解
2017/05/07 Javascript
浅谈vue自定义全局组件并通过全局方法 Vue.use() 使用该组件
2017/12/07 Javascript
vue中父子组件注意事项,传值及slot应用技巧
2018/05/09 Javascript
Angular实现模版驱动表单的自定义校验功能(密码确认为例)
2018/05/17 Javascript
三种Webpack打包方式(小结)
2018/09/19 Javascript
Vue单文件组件开发实现过程详解
2020/07/30 Javascript
[46:00]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第一局
2016/03/03 DOTA
解决python3 urllib 链接中有中文的问题
2018/07/16 Python
对pytorch中的梯度更新方法详解
2019/08/20 Python
pycharm 设置项目的根目录教程
2020/02/12 Python
用HTML5实现鼠标滚轮事件放大缩小图片的功能
2015/06/25 HTML / CSS
Speedo澳大利亚官网:全球领先游泳品牌
2018/02/04 全球购物
阿玛瑞酒店中文官方网站:Amari.com
2018/02/13 全球购物
阿姆斯特丹杜莎夫人蜡像馆官方网站:Madame Tussauds Amsterdam
2019/03/12 全球购物
英语演讲稿范文
2014/01/03 职场文书
物业保安岗位职责
2014/07/02 职场文书
群众路线班子对照检查材料
2014/09/25 职场文书
党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
2015年见习期个人工作总结
2015/05/28 职场文书
导游词之岳阳楼
2019/09/25 职场文书
Redis延迟队列和分布式延迟队列的简答实现
2021/05/13 Redis
python中opencv实现图片文本倾斜校正
2021/06/11 Python
简单聊聊Golang中defer预计算参数
2022/03/25 Golang