import struct,sys
from socket import *
from contextlib import closing
import hashlib,os
from functools import partial
from prettytable import PrettyTable #[liuzhuan] 引入表格
sha1_new = partial(hashlib.new, 'sha1')
SHA1_HASH_SIZE = 20
MULTI_RESULTS = 1 << 17
SECURE_CONNECTION = 1 << 15
CLIENT_PLUGIN_AUTH = 1 << 19
CLIENT_CONNECT_ATTRS = 1<< 20
CLIENT_PROTOCOL_41 = 1 << 9
CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA = 1<<21
CLIENT_DEPRECATE_EOF = 1 << 24
LONG_PASSWORD = 1
LONG_FLAG = 1 << 2
PROTOCOL_41 = 1 << 9
TRANSACTIONS = 1 << 13
CAPABILITIES = (
LONG_PASSWORD | LONG_FLAG | PROTOCOL_41 | TRANSACTIONS
| SECURE_CONNECTION | MULTI_RESULTS
| CLIENT_PLUGIN_AUTH | CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | CLIENT_CONNECT_ATTRS | CLIENT_DEPRECATE_EOF)
CLIENT_CONNECT_WITH_DB = 9
max_packet_size = 2 ** 24 - 1
charset_id = 45
class PreparPacket(object):
#类内函数实现
def __init__(self):
pass
#类内函数实现
def __null_bitmap(self,num_params):
_bytes = int((num_params + 7) / 8)
if _bytes == 1:
return bytearray(struct.pack('B',0))
elif _bytes == 2:
return bytearray(struct.pack('H', 0))
elif _bytes == 3:
return bytearray(struct.pack('HB', 0,0))
elif _bytes == 4:
return bytearray(struct.pack('I', 0))
#类内函数实现
def is_null(self,null_bytes,pos):
bit = null_bytes[int(pos / 8)]
if type(bit) is str:
bit = ord(bit)
return bit & (1 << (pos % 8))
#类内函数实现
def COM_Query(self, sql):
return struct.pack('B', 3) + sql.encode('utf8')
#类内函数实现
def COM_STMT_PREPARE(self,sql):
return struct.pack('B',0x16) + sql.encode('utf8')
#类内函数实现
def COM_STMT_EXECUTE(self,statement_id,flags,num_params,values,column_info):
_pack = struct.pack('
if num_params > 0:
_null_map = self.__null_bitmap(num_params)
for i,k in enumerate(values):
if k == None:
bytes_pos = int(i / 8)
bit_pos = int(i % 8)
_null_map[bytes_pos] |= 1 << bit_pos
_pack += _null_map + struct.pack('B',1)
_v = b''
for col_name in values:
col_type = 0x0f # default string
for col in column_info:
if col['name'].decode() == col_name:
col_type = col['type']
_pack += struct.pack('H',col_type)
if col_type in (0xfd,0xfe,0x0f):
_v += struct.pack('B',len(values[col_name]))
_v += values[col_name].encode('utf8')
elif col_type == 0x01:
_v += struct.pack('B',values[col_name])
elif col_type == 0x02:
_v += struct.pack('
elif col_type in (0x03,0x09):
_v += struct.pack('
elif col_type == 0x08:
_v += struct.pack('
return _pack + _v
#类内函数实现
def Prepar_head(self,playload_length,seq_id):
return struct.pack('
#类内函数实现
def handshakeresponsepacket(self,server_packet_info,user,password,database=None):
client_flag = 0
client_flag |= CAPABILITIES
if database:
client_flag |= CLIENT_CONNECT_WITH_DB
server_version = (server_packet_info['server_version']).decode()
if int(server_version.split('.', 1)[0]) >= 5:
client_flag |= MULTI_RESULTS
response_packet = struct.pack('
response_packet += user.encode() + b'\0'
sha1_password = self.sha1_password(password=password,auth_plugin_data=server_packet_info['auth_plugin_data'])
if server_packet_info['capability_flags'] & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA:
response_packet += struct.pack('!B',len(sha1_password)) + sha1_password
elif server_packet_info['capability_flags'] & SECURE_CONNECTION:
response_packet += struct.pack('B',len(sha1_password)) + sha1_password
else:
response_packet += sha1_password + b'\0'
if server_packet_info['capability_flags'] & CLIENT_CONNECT_WITH_DB:
if database:
response_packet += database.encode()
response_packet += b'\0'
if server_packet_info['capability_flags'] & CLIENT_PLUGIN_AUTH:
response_packet += b'' + b'\0'
if server_packet_info['capability_flags'] & CLIENT_CONNECT_ATTRS:
_connect_attrs = {
'_client_name': 'pymysql',
'_pid': str(os.getpi