init
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import base64
|
||||
from datetime import datetime, timezone
|
||||
import math
|
||||
from zoneinfo import ZoneInfo
|
||||
from flask import current_app, json
|
||||
import numpy as np
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
import threading # 用于线程安全
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util.Padding import unpad
|
||||
|
||||
|
||||
# --- 全局状态管理 ---
|
||||
# 使用一个简单的标志和锁来确保线程安全
|
||||
cluster_ensured_running = False
|
||||
cluster_check_lock = threading.Lock()
|
||||
|
||||
|
||||
def encrypt_password(raw_password: str) -> str:
|
||||
"""加密密码(使用pbkdf2:sha256算法)"""
|
||||
return generate_password_hash(raw_password, method="pbkdf2:sha256", salt_length=16)
|
||||
|
||||
|
||||
def verify_password(encrypted_password: str, raw_password: str) -> bool:
|
||||
"""验证密码"""
|
||||
return check_password_hash(encrypted_password, raw_password)
|
||||
|
||||
|
||||
def convert_incident_time_format(data_list):
|
||||
for item in data_list:
|
||||
# 原始数据是Timestamp类型,直接获取
|
||||
original_ts = item["incident_time"]
|
||||
print('original_ts',type(original_ts))
|
||||
# 1. 为Timestamp添加原时区(假设原时间是Asia/Shanghai时区,且原始Timestamp无时区)
|
||||
# 注意:如果Timestamp已有时区,直接跳过localize,用tz_convert即可
|
||||
if original_ts.tz is None: # 检查是否已有时区
|
||||
original_tz_ts = original_ts.tz_localize(ZoneInfo("Asia/Shanghai"))
|
||||
else:
|
||||
original_tz_ts = original_ts # 已有时区则直接使用
|
||||
|
||||
# 2. 转换为UTC时区
|
||||
utc_ts = original_tz_ts.tz_convert(ZoneInfo("UTC"))
|
||||
|
||||
# 3. 格式化输出目标格式(添加T、毫秒和时区标识)
|
||||
target_str = utc_ts.strftime("%Y-%m-%dT%H:%M:%S") + ".000+0000"
|
||||
|
||||
# 更新字段
|
||||
item["incident_time"] = target_str
|
||||
|
||||
|
||||
# 处理NaN的值
|
||||
# processed_data = {}
|
||||
for key, value in item.items():
|
||||
# 检查当前值是否为NaN(仅针对数值类型)
|
||||
if isinstance(value, (int, float)): # 确保是数值类型
|
||||
# 判断是否为NaN(同时兼容math.nan和np.nan)
|
||||
if math.isnan(value) or np.isnan(value):
|
||||
item[key] = None
|
||||
else:
|
||||
item[key] = value
|
||||
else:
|
||||
# 非数值类型(如字符串、None等)直接保留
|
||||
item[key] = value
|
||||
|
||||
return data_list
|
||||
|
||||
# gen5的车码查询前替换为真实的车码
|
||||
def mask_vin(real_vin):
|
||||
id_str = real_vin[-6:]
|
||||
if not id_str.isdigit():
|
||||
print('The last six digits of vin:%s are not numbers!' % real_vin)
|
||||
return real_vin
|
||||
masked_id = ''
|
||||
add = 0
|
||||
total = 0
|
||||
mapping = {
|
||||
73: 88,
|
||||
79: 89,
|
||||
81: 90,
|
||||
}
|
||||
for i in id_str:
|
||||
total += int(i)
|
||||
for i in id_str:
|
||||
add += total + 2
|
||||
c = int(i) + 65 + add % 13
|
||||
if c in [73, 79, 81]:
|
||||
c = mapping[c]
|
||||
masked_id += chr(c)
|
||||
|
||||
masked_vin = real_vin[:-6] + masked_id[::-1]
|
||||
|
||||
return masked_vin
|
||||
|
||||
|
||||
def decrypt_code(encrypted_data):
|
||||
try:
|
||||
raw_key=current_app.config['HEADERS_SECRET_KEY']
|
||||
key_bytes=raw_key.encode('utf-8')[:16]
|
||||
if len(key_bytes)<16:
|
||||
key_bytes=key_bytes.ljust(16,b"0")
|
||||
|
||||
combined=base64.b64decode(encrypted_data)
|
||||
iv_byte=combined[:16]
|
||||
ct_byte=combined[16:]
|
||||
|
||||
ciper=AES.new(key_bytes,AES.MODE_CBC,iv=iv_byte)
|
||||
des_padd=ciper.decrypt(ct_byte)
|
||||
|
||||
desrypt_res=unpad(des_padd,AES.block_size)
|
||||
|
||||
return desrypt_res.decode('utf-8')
|
||||
|
||||
except Exception as e:
|
||||
print('解析失败')
|
||||
return None
|
||||
Reference in New Issue
Block a user