Ptython Day11 数据编解码 及 例题分析

一、编解码基础概念

编解码指的是将数据从一种格式转换为另一种格式,其目的是为了更好地保证数据的传输和存储。

二、字符串的编解码

字符串的编解码主要涉及字符串与二进制流数据之间的转换。

2.1 编码(Encode)

  • 定义:将字符串以流(二进制数据)的形式来表示。
  • 方法:在 Python 中,字符串(str)通过encode(coder)方法实现编码,默认编码器为 utf-8。
  • 常见编码器:ascii、gbk(国标)、utf-8、unicode_escape(unicode 编码)。
  • 二进制流标识:在 Python 中,以b前缀开头的字符串代表二进制流数据(字符串流)。

2.2 解码(Decode)

  • 定义:将流数据以字符串的形式进行表示。
  • 方法:二进制流(bytes)通过decode(encoding = 'utf-8')方法进行解码。

2.3 不同编码下的字节占用示例

# 在 utf-8 编码下,一个汉字占用 3 个字节
string = 'hello python 你好'
print(string.encode('utf-8'))  # 输出:b'hello python \xe4\xbd\xa0\xe5\xa5\xbd'

# 在 gbk 编码下,一个汉字占用 2 个字节
print(string.encode('gbk'))

# 在 unicode 编码下,超出ascii范围的字符统一使用 \u + 十六进制表示法
print(string.encode('unicode_escape'))

# 汉字'你'的编码示例
print(ord('你'), bin(20320))  # ord()获取字符的Unicode码,bin()将十进制转为二进制

2.4 解码示例

date = b'abc'
print(date.decode('utf-8'))  # 将二进制流解码为字符串

三、Base64 编解码

3.1 概念

Base64 编解码是将二进制数据转换成 ASCII 字符,方便数据在网络中的传输和存储。

3.2 相关方法

  • base64.b64encode(bytes):将二进制流数据进行编码操作,返回一个 base64 编码后的字符串流。
  • base64.b64decode(str|bytes):将已编码的二进制流数据进行解码操作,并返回一个解码后的字符串流。

3.3 使用场景

  • 邮件发送图片、音频等二进制数据流
  • Basic 认证
  • Cookie 存储二进制数据
  • URL 中传输二进制数据
  • 图片的 date-url 格式

3.4 Base64 编解码示例

import base64

# 编码示例
message = 'hello 你好'
ret = base64.b64encode(message.encode())
print(ret.decode())  # 将编码后的二进制流转为字符串输出

# 解码示例
date = 'aGVsbG8g5L2g5aW9'
ret = base64.b64decode(date.encode())
print(ret.decode())

3.5 图片的 Base64 编码示例

# 打开图片文件并以二进制流方式读取
f = open(r'C:\Users\Administrator\Pictures\【哲风壁纸】动漫角色-名侦探柯南.png', 'rb')
bytes1 = f.read()
# 进行Base64编码并转为字符串
date = base64.b64encode(bytes1).decode()
# 拼接成图片的data-url格式
date = 'data:image/png;base64,' + date
# 生成img标签
img_tag = f"<img src='{date}'>"
# 将img标签写入html文件
w = open(r'C:\Users\Administrator\Desktop\01.html', 'w')
w.write(img_tag)
w.close()

四、特殊 URL 地址转换(迅雷、快车等)

4.1 迅雷地址转换规则

  1. 在原始地址的前后添加前缀AA和后缀ZZ
  2. 将处理后的字符串进行 base64 编码
  3. 再添加迅雷协议前缀thunder://

4.2 其他下载协议地址转换示例

# 快车(flashget)地址转换示例
url = 'flashget://W0ZMQVNIR0VUXWh0dHA6Ly93d3cucWlrdS5lZHUvW0ZMQVNIR0VUXQ=='
# 去除协议前缀
date = url.removeprefix('flashget://')
# 进行base64解码并转为字符串
date = base64.b64decode(date).decode()
# 去除前后标识
date = date.removeprefix('[FLASHGET]').removesuffix('[FLASHGET]')
print(date)

# QQ旋风(qqdl)地址转换示例
url = 'qqdl://aHR0cDovL3d3dy5xaWt1LmVkdS8='
date = url.removeprefix('qqdl://')
date = base64.b64decode(date).decode()
print(date)

五、函数定义与使用(求和、判断闰年等)

5.1 函数定义语法

def <函数名>(<参数列表>):
    函数体

5.2 函数调用

通过函数名进行调用,后面紧跟小括号。

5.3 函数返回值

return 语句在调用函数时会立马结束函数的调用,并返回 return 的结果给调用者。

5.4 具体函数示例

5.4.1 求指定范围数字的和

def sum_range(a, b):
    s = 0
    for i in range(a, b + 1):
        s += i
    return s

# 调用示例
print(sum_range(1, 100))  # 输出1~100所有数字的和
print(sum_range(100, 300))  # 输出100~300所有数字的和
print(sum_range(50, 100))  # 输出50~100所有数字的和
print(sum_range(1, 100) * 20)  # 输出1~100所有数字的和乘以20的结果
5.4.2 求两个数字的和

def sum_number(a, b):
    """
    求两个数的和
    :param a: 第一个数字
    :param b: 第二个数字
    :return: 两个数字的和
    """
    c = a + b
    return c
5.4.3 判断某个年份是否是闰年

def is_leap_year(year):
    """
    判断指定的年份是否是闰年
    :param year: 待判断的年份
    :return: 如果是闰年返回True,否则返回False
    """
    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0

5.4.4 求两个数字的商和余数

def div_mod(a, b):
    """
    求两个数字的商和余数
    :param a: 被除数
    :param b: 除数
    :return: 商和余数组成的元组
    """
    return a // b, a % b

# 调用示例
ret = div_mod(3, 4)
print(ret)  # 输出:(0, 3)
print(*ret)  # 解包输出:0 3

一、下载协议地址转换函数

1. 快车地址解析为原始网址

import base64

def parse_flashget_to_url(url):
    """
    根据快车地址解析原始地址
    :param url: 快车地址(以flashget://开头)
    :return: 解析后的原始网址
    """
    # 去除快车协议前缀
    url = url.removeprefix('flashget://')
    # 进行base64解码并转为字符串
    url = base64.b64decode(url).decode()
    # 去除前后的[FLASHGET]标识
    url = url.removeprefix('[FLASHGET]').removesuffix('[FLASHGET]')
    return url

# 示例调用
print(parse_flashget_to_url('flashget://W0ZMQVNIR0VUXWh0dHA6Ly90b29sLmx1L3Rlc3QuemlwW0ZMQVNIR0VUXQ=='))

2. 网址转换为快车地址

def convert_url_to_flash_get(url):
    """
    将原始网址转换为快车地址
    :param url: 原始网址
    :return: 转换后的快车地址
    """
    # 前后添加[FLASHGET]标识
    url = '[FLASHGET]' + url + '[FLASHGET]'
    # 进行base64编码并转为字符串
    url = base64.b64encode(url.encode()).decode()
    # 添加快车协议前缀
    return 'flashget://' + url

# 示例调用
print(convert_url_to_flash_get('http://tool.lu/test.zip'))

3. 网址转换为迅雷地址

def convert_url_to_thunder(url):
    """
    将原始网址转换为迅雷地址
    :param url: 原始网址
    :return: 转换后的迅雷地址
    """
    # 前后添加AA和ZZ前缀后缀
    url = 'AA' + url + 'ZZ'
    # 进行base64编码并转为字符串
    url = base64.b64encode(url.encode()).decode()
    # 添加迅雷协议前缀
    return 'thunder://' + url

# 示例调用
print(convert_url_to_thunder('http://google.com'))

4. 网址转换为 QQ 旋风地址

def convert_url_to_qqdl(url):
    """
    将原始网址转换为QQ旋风地址
    :param url: 原始网址
    :return: 转换后的QQ旋风地址
    """
    # 进行base64编码并转为字符串
    url = base64.b64encode(url.encode()).decode()
    # 添加QQ旋风协议前缀
    return 'qqdl://' + url

# 示例调用
print(convert_url_to_qqdl('http://google.com'))

5. QQ 旋风地址转换为迅雷地址

def convert_qqdl_to_thunder(qqdl_url):
    """
    将QQ旋风地址转换为迅雷地址
    :param qqdl_url: QQ旋风地址(以qqdl://开头)
    :return: 转换后的迅雷地址
    """
    # 去除QQ旋风协议前缀并解码
    url = base64.b64decode(qqdl_url.removeprefix('qqdl://')).decode()
    # 按照迅雷规则处理
    url = 'AA' + url + 'ZZ'
    # 编码并添加迅雷协议前缀
    url = 'thunder://' + base64.b64encode(url.encode()).decode()
    return url

# 示例调用
print(convert_qqdl_to_thunder('qqdl://aHR0cDovL3Rvb2wubHUvdGVzdC56aXA='))

二、其他函数实现

1. 获取列表中的最大和最小元素

def max_and_min(lst):
    """
    获取列表中的最大和最小元素(不使用内置max和min函数)
    :param lst: 待处理的列表
    :return: (最小值,最大值)组成的元组
    """
    # 对列表进行排序
    lst.sort()
    # 返回第一个元素(最小值)和最后一个元素(最大值)
    return lst[0], lst[-1]

# 示例调用
print(max_and_min([11, 22, 55, 4, 6, 184, 1, 5]))

2. 判断指定年份是否为闰年

def is_leap_year(year):
    """
    判断指定年份是否为闰年
    :param year: 待判断的年份
    :return: 是闰年返回True,否则返回False
    """
    # 闰年规则:能被4整除且不能被100整除,或能被400整除
    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0

# 示例调用
print(is_leap_year(1999))

3. 实现列表的选择排序

def selectionSort(lst):
    """
    对列表进行选择排序(升序)
    :param lst: 待排序的列表
    :return: 排序后的列表
    """
    # 外层循环控制需要排序的元素位置
    for i in range(len(lst) - 1):
        # 内层循环寻找最小元素并与当前位置交换
        for j in range(i + 1, len(lst)):
            if lst[i] > lst[j]:
                lst[i], lst[j] = lst[j], lst[i]
    return lst

# 示例调用
print(selectionSort([5, 4, 3, 2, 1]))

4. 判断字符串中是否包含字母

def has_letter(string):
    """
    判断字符串中是否包含字母
    :param string: 待判断的字符串
    :return: 包含字母返回True,否则返回False
    """
    for char in string:
        if char.isalpha():
            return True
    return False

# 示例调用
print(has_letter('AAA44546'))

5. 判断字符串中是否包含数字

def has_number(string):
    """
    判断字符串中是否包含数字
    :param string: 待判断的字符串
    :return: 包含数字返回True,否则返回False
    """
    for char in string:
        if char.isdigit():
            return True
    return False

# 示例调用
print(has_number('dasfassdfasf1'))

6. 获取字符串中数字的个数

def get_number_count(string):
    """
    统计字符串中数字的个数
    :param string: 待统计的字符串
    :return: 数字的个数
    """
    count = 0
    for char in string:
        if char.isdigit():
            count += 1
    return count

# 示例调用
print(get_number_count("dsafasd545fadf4ds"))

7. 判断字符串是否是纯大写字母

def is_upper_letter(string):
    """
    判断字符串是否由纯大写字母组成
    :param string: 待判断的字符串
    :return: 是纯大写字母返回True,否则返回False
    """
    # 先判断是否全是字母,再判断是否全是大写
    return string.isalpha() and string.isupper()

# 示例调用
print(is_upper_letter('ABC214165'))

8. 获取指定日期对应的星期(蔡勒公式)

def get_week(year, month, day=1):
    """
    根据蔡勒公式获取指定日期对应的星期
    :param year: 年份
    :param month: 月份
    :param day: 日期,默认为1
    :return: 星期几(字符串)
    """
    D = day  # 日
    
    # 处理月份转换(3月为1,2月为12,且年份减1)
    if 3 <= month <= 12:
        M = month - 2
    else:
        M = month + 10
        year -= 1
    
    C = year // 100  # 年的前两位数
    Y = year % 100    # 年的后两位数
    
    # 应用蔡勒公式计算
    W = ((26 * M - 2) // 10 + D + Y + Y // 4 + C // 4 - 2 * C) % 7
    
    # 处理负数情况
    if W < 0:
        W += 7
    
    # 转换为星期字符串
    week_list = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
    return week_list[W]

# 示例调用
print(get_week(2025, 7, 9))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值