代码拉取完成,页面将自动刷新
package main
import (
"encoding/binary"
"fmt"
"math"
"time"
)
func parseTiny(data []byte, pos *int) (int8, error) {
if *pos >= len(data) {
return 0, fmt.Errorf("数据不足以解析TINY")
}
val := int8(data[*pos])
*pos++
return val, nil
}
func parseShort(data []byte, pos *int) (int16, error) {
if *pos+2 > len(data) {
return 0, fmt.Errorf("数据不足以解析SHORT")
}
val := int16(binary.LittleEndian.Uint16(data[*pos : *pos+2]))
*pos += 2
return val, nil
}
func parseLong(data []byte, pos *int) (int32, error) {
if *pos+4 > len(data) {
return 0, fmt.Errorf("数据不足以解析LONG")
}
val := int32(binary.LittleEndian.Uint32(data[*pos : *pos+4]))
*pos += 4
return val, nil
}
func parseFloat(data []byte, pos *int) (float32, error) {
if *pos+4 > len(data) {
return 0, fmt.Errorf("数据不足以解析FLOAT")
}
bits := binary.LittleEndian.Uint32(data[*pos : *pos+4])
*pos += 4
return math.Float32frombits(bits), nil
}
func parseDouble(data []byte, pos *int) (float64, error) {
if *pos+8 > len(data) {
return 0, fmt.Errorf("数据不足以解析DOUBLE")
}
bits := binary.LittleEndian.Uint64(data[*pos : *pos+8])
*pos += 8
return math.Float64frombits(bits), nil
}
func parseLongLong(data []byte, pos *int) (int64, error) {
if *pos+8 > len(data) {
return 0, fmt.Errorf("数据不足以解析LONGLONG")
}
val := int64(binary.LittleEndian.Uint64(data[*pos : *pos+8]))
*pos += 8
return val, nil
}
func parseVarString(data []byte, pos *int) (string, error) {
if *pos+1 > len(data) {
return "", fmt.Errorf("数据不足以解析VAR_STRING长度")
}
length := int(data[*pos])
*pos++
if *pos+length > len(data) {
return "", fmt.Errorf("数据不足以解析VAR_STRING内容")
}
val := string(data[*pos : *pos+length])
*pos += length
return val, nil
}
func parseDate(data []byte, pos *int) (string, error) {
if *pos+3 > len(data) {
return "", fmt.Errorf("数据不足以解析DATE")
}
year := int(binary.LittleEndian.Uint16(data[*pos : *pos+2]))
month := int(data[*pos+2])
day := int(data[*pos+3])
*pos += 4
return fmt.Sprintf("%04d-%02d-%02d", year, month, day), nil
}
func parseTime(data []byte, pos *int) (string, error) {
if *pos+3 > len(data) {
return "", fmt.Errorf("数据不足以解析TIME")
}
negative := data[*pos]&0x80 != 0
days := int(binary.LittleEndian.Uint32(data[*pos : *pos+4]))
hours := int(data[*pos+4])
minutes := int(data[*pos+5])
seconds := int(data[*pos+6])
*pos += 7
sign := ""
if negative {
sign = "-"
}
return fmt.Sprintf("%s%d %02d:%02d:%02d", sign, days, hours, minutes, seconds), nil
}
func parseDatetime(data []byte, pos *int) (string, error) {
if *pos+8 > len(data) {
return "", fmt.Errorf("数据不足以解析DATETIME")
}
date, err := parseDate(data, pos)
if err != nil {
return "", err
}
time, err := parseTime(data, pos)
if err != nil {
return "", err
}
return fmt.Sprintf("%s %s", date, time), nil
}
func parseTimestamp(data []byte, pos *int) (string, error) {
if *pos+4 > len(data) {
return "", fmt.Errorf("数据不足以解析TIMESTAMP")
}
unixTime := int64(binary.LittleEndian.Uint32(data[*pos : *pos+4]))
*pos += 4
t := time.Unix(unixTime, 0).UTC()
return t.Format("2006-01-02 15:04:05"), nil
}
func isPrepareResponse(packet []byte) bool {
// Prepare响应的特征:
// 1. 第一个字节是0x00(OK包)
// 2. 接下来是4字节的statement_id
// 3. 然后是2字节的列数
// 4. 再然后是2字节的参数数
// 5. 1字节的填充(0x00)
// 6. 2字节的警告数
if len(packet) < 12 {
return false
}
// 检查填充字节是否为0x00
if packet[9] != 0x00 {
return false
}
// 其他字段应该包含有效的值
statementID := binary.LittleEndian.Uint32(packet[1:5])
columnCount := binary.LittleEndian.Uint16(packet[5:7])
paramCount := binary.LittleEndian.Uint16(packet[7:9])
// statement_id 应该大于0,列数和参数数可以为0
return statementID > 0 && (columnCount > 0 || paramCount > 0)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。