V1.0.0
This commit is contained in:
152
tool.py
Normal file
152
tool.py
Normal file
@@ -0,0 +1,152 @@
|
||||
'''
|
||||
Author: 于小丘 海枫
|
||||
Date: 2024-10-02 15:23:34
|
||||
LastEditors: Yuerchu admin@yuxiaoqiu.cn
|
||||
LastEditTime: 2024-11-29 20:05:42
|
||||
FilePath: /Findreve/tool.py
|
||||
Description: Findreve 小工具 tool
|
||||
|
||||
Copyright (c) 2018-2024 by 于小丘Yuerchu, All Rights Reserved.
|
||||
'''
|
||||
|
||||
import string
|
||||
import random
|
||||
import hashlib
|
||||
import binascii
|
||||
import logging
|
||||
import qrcode
|
||||
from typing import Optional
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
import base64
|
||||
from datetime import datetime, timezone, timedelta
|
||||
import os
|
||||
|
||||
def format_phone(phone: str, groups: list = None, separator: str = " ", private: bool = False) -> str:
|
||||
"""
|
||||
格式化中国大陆的11位手机号
|
||||
|
||||
:param phone: 手机号
|
||||
:param groups: 分组长度列表
|
||||
:param separator: 分隔符
|
||||
:param private: 是否隐藏前七位
|
||||
|
||||
:return: 格式化后的手机号
|
||||
"""
|
||||
if groups is None:
|
||||
groups = [3, 4, 4]
|
||||
|
||||
result = []
|
||||
start = 0
|
||||
for i, length in enumerate(groups):
|
||||
segment = phone[start:start + length]
|
||||
# 如果是private模式,将前两组(前7位)替换为星号
|
||||
if private and i < 2:
|
||||
segment = "*" * length
|
||||
result.append(segment)
|
||||
start += length
|
||||
|
||||
return separator.join(result)
|
||||
|
||||
def generate_password(length: int = 8) -> str:
|
||||
# 定义密码字符集,大小写字母和数字
|
||||
characters = string.ascii_letters + string.digits
|
||||
# 随机选择length个字符,生成密码
|
||||
password = ''.join(random.choice(characters) for i in range(length))
|
||||
return password
|
||||
|
||||
def hash_password(password: str) -> str:
|
||||
"""
|
||||
生成密码的加盐哈希值。
|
||||
|
||||
:param password: 需要哈希的原始密码
|
||||
:type password: str
|
||||
:return: 包含盐值和哈希值的字符串
|
||||
:rtype: str
|
||||
|
||||
使用SHA-256和PBKDF2算法对密码进行加盐哈希,返回盐值和哈希值的组合。
|
||||
"""
|
||||
salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
|
||||
pwdhash = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000)
|
||||
pwdhash = binascii.hexlify(pwdhash)
|
||||
return (salt + pwdhash).decode('ascii')
|
||||
|
||||
def verify_password(stored_password: str, provided_password: str, debug: bool = False) -> bool:
|
||||
"""
|
||||
验证存储的密码哈希值与用户提供的密码是否匹配。
|
||||
|
||||
:param stored_password: 存储的密码哈希值(包含盐值)
|
||||
:type stored_password: str
|
||||
:param provided_password: 用户提供的密码
|
||||
:type provided_password: str
|
||||
:param debug: 是否输出调试信息,将会输出原密码和哈希值
|
||||
:type debug: bool
|
||||
:return: 如果密码匹配返回True,否则返回False
|
||||
:rtype: bool
|
||||
|
||||
从存储的密码哈希中提取盐值,使用相同的哈希算法验证用户提供的密码。
|
||||
"""
|
||||
salt = stored_password[:64]
|
||||
stored_password = stored_password[64:]
|
||||
pwdhash = hashlib.pbkdf2_hmac('sha256',
|
||||
provided_password.encode('utf-8'),
|
||||
salt.encode('ascii'),
|
||||
100000)
|
||||
pwdhash = binascii.hexlify(pwdhash).decode('ascii')
|
||||
if debug:
|
||||
logging.info(f"原密码: {provided_password}, 哈希值: {pwdhash}, 存储哈希值: {stored_password}")
|
||||
return pwdhash == stored_password
|
||||
|
||||
def format_time_diff(target_time: datetime | str) -> str:
|
||||
"""
|
||||
计算目标时间与当前时间的差值,返回易读的中文描述
|
||||
|
||||
Args:
|
||||
target_time: 目标时间,可以是datetime对象或时间字符串
|
||||
|
||||
Returns:
|
||||
str: 格式化的时间差描述,如"一年前"、"3个月前"等
|
||||
"""
|
||||
# 如果输入是字符串,先转换为datetime对象
|
||||
if isinstance(target_time, str):
|
||||
try:
|
||||
target_time = datetime.fromisoformat(target_time)
|
||||
except ValueError:
|
||||
return "时间格式错误"
|
||||
|
||||
now = datetime.now(timezone.utc)
|
||||
target_time = target_time.astimezone(timezone.utc)
|
||||
diff = now - target_time
|
||||
|
||||
# 如果是未来时间
|
||||
if diff.total_seconds() < 0:
|
||||
diff = -diff
|
||||
suffix = "后"
|
||||
else:
|
||||
suffix = "前"
|
||||
|
||||
seconds = diff.total_seconds()
|
||||
|
||||
# 定义时间间隔
|
||||
intervals = [
|
||||
(31536000, " 年"),
|
||||
(2592000, " 个月"),
|
||||
(86400, " 天"),
|
||||
(3600, " 小时"),
|
||||
(60, " 分钟"),
|
||||
(1, " 秒")
|
||||
]
|
||||
|
||||
# 计算最适合的时间单位
|
||||
for seconds_in_unit, unit in intervals:
|
||||
if seconds >= seconds_in_unit:
|
||||
value = int(seconds / seconds_in_unit)
|
||||
if unit == "个月" and value >= 12: # 超过12个月显示为年
|
||||
continue
|
||||
return f"{value}{unit}{suffix}"
|
||||
|
||||
return f"刚刚"
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(format_phone("18888888888", private=True))
|
||||
print(format_phone("18888888888", private=False))
|
||||
Reference in New Issue
Block a user