当前位置: 首页 > news >正文

文件结构与数据分析专项-解析

https://exam.didctf.com/practice/questions可以找到题目

出这套题主要是想鼓励大家在遇到陌生的文件时,可以主动地去对这类文件进行分析(尤其是将多个文件打包在一起),希望能通过专项练习得到这方面的提升。

源码

这边先给出源码,先是main.go

package mainimport ("crypto/rand""fmt"
)func main() {key := make([]byte, 256)if _, err := rand.Read(key); err != nil {fmt.Println("Error generating key:", err)return}if err := PackDir("files", "output.pak", key); err != nil {panic(err)}if err := UnpackFile("output.pak", "output"); err != nil {panic(err)}
}

然后是packer.go,这里就是主要逻辑

package mainimport ("bytes""compress/gzip""crypto/rc4""encoding/binary""fmt""io""os""path/filepath""sync""syscall""time""unsafe"
)type Packer struct {Header    [4]byteFileCount uint32RC4Key    [256]byte
}type FileInfo struct {CreateTime  uint64ModifyTime  uint64FileSize    uint64GzipSize    uint64FileNameLen uint16FileName    stringFileData    []byte
}var pool = &sync.Pool{New: func() interface{} {return &syscall.Filetime{}},
}func uint64FromFiletime(filetime *syscall.Filetime) uint64 {result := *(*uint64)(unsafe.Pointer(filetime))return result
}func Timestamp(t time.Time) uint64 {filetime := pool.Get().(*syscall.Filetime)defer pool.Put(filetime)*filetime = syscall.NsecToFiletime(t.UnixNano())return uint64FromFiletime(filetime)
}func FileTime(t syscall.Filetime) uint64 {return uint64FromFiletime(&t)
}func GzipCompress(data []byte) ([]byte, error) {var buf bytes.Bufferw := gzip.NewWriter(&buf)_, err := w.Write(data)if err != nil {return nil, err}w.Close()return buf.Bytes(), nil
}func GzipDecompress(data []byte) ([]byte, error) {r, err := gzip.NewReader(bytes.NewReader(data))if err != nil {return nil, err}defer r.Close()return io.ReadAll(r)
}func Rc4Encrypt(key, data []byte) []byte {dst := make([]byte, len(data))c, _ := rc4.NewCipher(key)c.XORKeyStream(dst, data)return dst
}func DeriveNextKey(prevData, baseKey []byte) []byte {if len(prevData) >= 256 {return prevData[len(prevData)-256:]}need := 256 - len(prevData)newKey := append([]byte{}, prevData...)newKey = append(newKey, baseKey[:need]...)return newKey
}func PackDir(dir, outFile string, baseKey []byte) error {entries, err := os.ReadDir(dir)if err != nil {return err}var packer Packercopy(packer.Header[:], []byte("PACK"))copy(packer.RC4Key[:], baseKey[:256])buf := new(bytes.Buffer)if err := binary.Write(buf, binary.LittleEndian, &packer); err != nil {return err}curKey := packer.RC4Key[:]fileCount := uint32(0)for _, entry := range entries {if entry.IsDir() {continue}path := filepath.Join(dir, entry.Name())info, err := os.Stat(path)if err != nil {return err}data, err := os.ReadFile(path)if err != nil {return err}gz, err := GzipCompress(data)if err != nil {return err}enc := Rc4Encrypt(curKey, gz)var ctime, mtime time.Timeif stat, ok := info.Sys().(*syscall.Win32FileAttributeData); ok {ctime = time.Unix(0, stat.CreationTime.Nanoseconds())mtime = time.Unix(0, stat.LastWriteTime.Nanoseconds())} else {ctime = info.ModTime()mtime = info.ModTime()}fi := FileInfo{CreateTime:  Timestamp(ctime),ModifyTime:  Timestamp(mtime),FileSize:    uint64(info.Size()),GzipSize:    uint64(len(enc)),FileNameLen: uint16(len(entry.Name())),FileName:    entry.Name(),FileData:    enc,}if err := binary.Write(buf, binary.LittleEndian, fi.CreateTime); err != nil {return err}if err := binary.Write(buf, binary.LittleEndian, fi.ModifyTime); err != nil {return err}if err := binary.Write(buf, binary.LittleEndian, fi.FileSize); err != nil {return err}if err := binary.Write(buf, binary.LittleEndian, fi.GzipSize); err != nil {return err}if err := binary.Write(buf, binary.LittleEndian, fi.FileNameLen); err != nil {return err}if _, err := buf.Write([]byte(fi.FileName)); err != nil {return err}if _, err := buf.Write(fi.FileData); err != nil {return err}fileCount++curKey = DeriveNextKey(gz, packer.RC4Key[:])}packer.FileCount = fileCountout := buf.Bytes()binary.LittleEndian.PutUint32(out[4:8], fileCount)return os.WriteFile(outFile, out, 0644)
}func UnpackFile(packFile, outDir string) error {data, err := os.ReadFile(packFile)if err != nil {return err}buf := bytes.NewReader(data)var p Packerif err := binary.Read(buf, binary.LittleEndian, &p); err != nil {return err}curKey := p.RC4Key[:]for i := uint32(0); i < p.FileCount; i++ {var fi FileInfoif err := binary.Read(buf, binary.LittleEndian, &fi.CreateTime); err != nil {return err}if err := binary.Read(buf, binary.LittleEndian, &fi.ModifyTime); err != nil {return err}if err := binary.Read(buf, binary.LittleEndian, &fi.FileSize); err != nil {return err}if err := binary.Read(buf, binary.LittleEndian, &fi.GzipSize); err != nil {return err}if err := binary.Read(buf, binary.LittleEndian, &fi.FileNameLen); err != nil {return err}name := make([]byte, fi.FileNameLen)if _, err := io.ReadFull(buf, name); err != nil {return err}fi.FileName = string(name)enc := make([]byte, fi.GzipSize)if _, err := io.ReadFull(buf, enc); err != nil {return err}dec := Rc4Encrypt(curKey, enc)raw, err := GzipDecompress(dec)if err != nil {return err}outPath := filepath.Join(outDir, fi.FileName)if err := os.WriteFile(outPath, raw, 0644); err != nil {return err}fmt.Println("Unpacked:", outPath)curKey = DeriveNextKey(dec, p.RC4Key[:])}return nil
}

出题思路

先准备若干文件,这里模拟的是一个传销平台场景,数据用python生成,插入到数据库(纯粹是为了解答案方便)当中,然后导出作为待打包文件,包含数据文件和表结构文件。

设定的打包文件逻辑是,在文件中存储一些元数据,包括文件数量、创建时间、修改时间、原始大小、压缩后大小、文件名称。然后对原始数据进行压缩,并使用rc4加密,初始密钥随机,后续文件密钥使用上一个文件压缩结果的后256字节。

这样下来如果想要解包,则需要先找到初始密钥,然后解密第一个文件,得到压缩后的数据,再用最后256字节继续向下解密,如此往复。

为了简便,只实现了打包1个目录下的文件,没有做递归这些,编译时注释掉解包代码。

import random
import pymysql
from faker import Faker
from datetime import datetime, timedelta# 数据库连接配置
DB_CONFIG = {"host": "192.168.31.5","user": "root","password": "123456","database": "test","charset": "utf8mb4"
}faker = Faker("zh_CN")  # 生成中文数据# 插入会员数据
def insert_members(cursor, total_members=100):members = []start_time = datetime(2008, 1, 1, 0, 0, 0)for i in range(1, total_members + 1):nickname = faker.user_name()gender = random.choice([0, 1, 2])real_name = faker.name()mobile = faker.phone_number()id_card = faker.ssn()address = faker.address()bank_card = faker.credit_card_number()# 创建时间随机递增 1~5 小时if i == 1:create_time = start_timeelse:delta_hours = random.randint(1, 5)create_time = members[-1]["create_time"] + timedelta(hours=delta_hours)# 上级会员逻辑if i == 1:superior_id = Noneelse:candidate_size = max(5, int((i - 1) * 0.5))start_id = max(1, i - candidate_size)superior_id = random.randint(start_id, i - 1)member = {"member_id": i,"nickname": nickname,"gender": gender,"real_name": real_name,"mobile": mobile,"id_card": id_card,"address": address,"bank_card": bank_card,"superior_id": superior_id,"wallet_balance": 0.00,"create_time": create_time}members.append(member)cursor.execute("""INSERT INTO member (member_id, nickname, gender, real_name, mobile, id_card, address, bank_card, superior_id, wallet_balance, create_time)VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)""", (member["member_id"],member["nickname"],member["gender"],member["real_name"],member["mobile"],member["id_card"],member["address"],member["bank_card"],member["superior_id"],member["wallet_balance"],member["create_time"]))return members# 插入流水数据
def insert_transaction_flows(cursor, members, total_flows=300):flows = []flow_id = 1members_with_flows = random.sample(members, k=len(members) // 2)for _ in range(total_flows):member = random.choice(members)if member not in members_with_flows and random.random() < 0.5:member = random.choice(members_with_flows)member_id = member["member_id"]wallet_balance = member["wallet_balance"]# 流水时间递增 1~200 分钟if flows:last_time = flows[-1]["create_time"]else:last_time = member["create_time"]delta_minutes = random.randint(1, 10)create_time = last_time + timedelta(seconds=delta_minutes)amount = random.randint(100, 1000)if wallet_balance <= 0:flow_type = 1else:flow_type = random.choice([1, 2])if flow_type == 1:new_balance = wallet_balance + amountelse:new_balance = wallet_balance - amountif new_balance < 0:flow_type = 1new_balance = wallet_balance + amountmember["wallet_balance"] = new_balanceflow = {"flow_id": flow_id,"member_id": member_id,"flow_type": flow_type,"amount": amount,"create_time": create_time}flows.append(flow)cursor.execute("""INSERT INTO transaction_flow (flow_id, member_id, flow_type, amount, create_time)VALUES (%s,%s,%s,%s,%s)""", (flow["flow_id"],flow["member_id"],flow["flow_type"],flow["amount"],flow["create_time"]))flow_id += 1def main():conn = pymysql.connect(**DB_CONFIG)cursor = conn.cursor()try:print("插入会员数据中...")members = insert_members(cursor, total_members=3500000)conn.commit()# print("插入流水数据中...")# insert_transaction_flows(cursor, members, total_flows=456789)# conn.commit()print("数据插入完成!")except Exception as e:conn.rollback()print("发生错误:", e)finally:cursor.close()conn.close()if __name__ == "__main__":main()

解题过程

首先的2题,让查看packer.exe的信息,此时一般就会使用DIE、EXEInfoPe这类工具,再看后面的问题,应当养成习惯,先用IDA加载了再说。

IDA9.2之前,对go的字符串支持几乎为0,可以用BinaryNinja替代,9.2开始可以正常反编译出字符串(如果能看到字符串,则会有比较大的突破)

1、2跳过,来到第3题

文件output.pak是由packer.exe生成的文件,该文件中包含了几个文件?(答案格式:0)

先来看反编译结果,可以清晰地看到程序可能使用了rc4、gzip、timestamp这几样东西,并且打包函数是main_PackDir

这里可以看到v61,他声明的长度是264,为什么是这个数?并且还有字符串PACK在,这占了4个字节,后面的从第9个字节开始的256个字节从a5中复制过来,这是之前main中的v3,通过crypto_rand_Read生成了256字节的随机密钥

也就是说,目前文件头部的结构是PACK+4字节+256字节随机密钥,那中间的4字节是什么呢?结合提问其实就可以猜测,它就是记录的文件数量,我们带着猜测看一下他的赋值

这里可以看到v15由v60+1得来,从宏观看这部分的代码,其实就是在循环中记录+1,这里就可以确定结果了

此时查看文件内容,就可以知道打包了4个文件

此外,在ida解析出的LocalTypes中可以看到这个结构体(不知道为啥另一个结构体看不到),可以很轻松得到结果

到这里,3、4、5、6、7都可以解出来了,密钥是

文件output.pak是由packer.exe生成的文件,该文件中包含了几个文件?(答案格式:0)
文件output.pak中存在一个密钥,该密钥的长度是多少字节?(答案格式:0)
给出密钥的MD5值。(答案格式:e10adc3949ba59abbe56e057f20f883e)
output.pak中包含的文件使用的加密算法是什么?(答案格式:des)
output.pak中包含的文件使用的压缩算法是什么?(答案格式:zip)4F7C6DA92323508E512FC92952F0D4552B164894107FC252621391F9978F61EB1A3D1915BFFE70931D326F9972721ACEEB813B7C6D3E4CA29699DCEF2171CAC043675C7B5F61A98F5CDE6439435CFF60EC76915C7E0DFFDAE9EB89596DC6A5B8B2E0DF61E415E78AC1C1BBF6F056EC4E74C15891DFC942EB732832022651ADC60EA139C993733C17C19D60137375C363E9693B7E0E04BCBAAEF89D14D70D752A8DF0525A6D3C9A78E583774DEA272B57038401BA9C27F54DBB8585FEDA71DF4A46D036AB1795ED75BA866189F57D130B8A9891515F2EC7659E956258F3FCCED8D6A741D6F80109A140B69550DF7650FC51DA590E96EAA2F82222B90F4E16AC09

接下来是8、9、10

member.txt的原始大小是多少字节?(答案格式:10086)
member.txt被压缩后的大小是多少字节?(答案格式:10086)
创建时间为北京时间2025-09-09 11:59:38的文件的文件名是什么?(答案格式:abc123.def)

从反编译的结果来看,就是循环读取文件、压缩、加密

然后一步步写进文件

我们侧重一下看写入的是啥,其实主要是跟v94有关,这里先连着写了4个8字节的uint64数据

接着写了1个2字节的uint16数据,然后写入了1个字符串v119(go中的字符串会包含地址和长度),最后将剩下的数据写入,最后面的v94[7],向上跟一下就知道是加密结果

最先写入的v82和v80,显然能看到是时间戳,不难看出获取的是WindowsFileTime

那么我们回到打包后的文件确认一下,确实如此,现在需要找到的是两个时间分别表示什么,从下面的数据来看,第二个时间是大于第一个时间的,虽然在秒级上是一样的,但是FileTime是100纳秒级,还是能看出差别

结合题目会问的创建时间,可以推测其中一个是创建时间,那么另一个就是修改时间或者访问时间,但是从代码里看简直就是灾难

这里我们可以回到main中,能够知道程序会读取files目录,然后生成output.pak文件,那么为何不执行一次呢?

新建一个files目录,导入1个文件,然后执行,对比结果。这样就可以知道,前面一个是创建时间,后面一个是修改时间(到底是修改时间还是访问时间,保存文件后,过一会再打开,就可以使这俩个值不一样了,比对一下就能知道)

还记得程序是连续写入了4个8字节的uint64,1个2字节的uint16吗?现在我们可以比对了,前面2个是时间,那后面2个呢?从题目的提问来看,大概率是文件大小相关的内容。

我们其实已经可以看见,第3个uint64的值是4,对应了文件大小4字节,第4个uint64的值是28,根据提问,这就对应了压缩后的字节大小(由于压缩算法需要包含一些元数据,特别小的文件压缩后可能会变大),又由于我们使用的加密算法是RC4,不会影响数据长度,所以获得密钥后就可以直接解析了。

接下来的uint16和字符串就很清晰了,uint16的值是7,字符串是aaa.txt,显然分别对应文件名长度和文件名称

从反编译的结果来看,就是读取了目录下的所有文件,然后遍历这些文件进行处理,最后读取了创建时间、修改时间、文件大小、文件名这些数据并写入结构体

接下来是11、12两题

packer.exe在进行一次打包时,使用的密钥是否会发生变化?(答案格式:是或否)
member.txt的MD5值是多少?(答案格式:e10adc3949ba59abbe56e057f20f883e)

第11题显然提醒我们,在单词打包中,密钥可能会发生变化,同时,这里也降低了难度,member.txt是打包的第一个文件,他的密钥是存储在文件头部的,所以无须写出完整的unpacker也能拿到这个文件并做一些题目

我们之前分析过,v61后面就是密钥

这里v116是压缩结果,v98就是对应的密钥,那么这里不难发现,每次循环,v98都是由v14进行赋值

根据v71进行判断,分成小于256和小于等于256两种情况

显然用后者更方便,else里面只有3行代码,v93就是压缩结果,v71是长度,这一段意思就是取最后256字节

而else之前,可以分析出,获取256-压缩长度,将压缩结果和初始密钥对应长度的数据拼接得到新的密钥

这样一来,我们就可以实现解包函数了,具体逻辑为

1.获取文件数量,确认要解包的文件数
2.读取初始密钥
3.读取元数据(创建时间、修改时间、文件大小、文件名等)
4.依据压缩结果长度,从文件名之后读取对应长度的数据,用初始密钥进行解密、解压
5.后续如此循环往复,但密钥需要根据之前的解密结果生成,数据大于等于256字节时,直接取最后256字节为密钥,否则和初始密钥拼接,取前256字节

后续数据分析部分,直接给sql

当前余额和流水不符的会员ID有?(答案格式:12,13,14)
层级关系一共有多少层?(答案格式:1)
第100层有多少会员?(答案格式:1)
性别和身份证号码能对应上的会员数量?(答案格式:1)

计算流水不符的情况

select m.member_id,m.wallet_balance,a.balance from member m
left join (select tf.member_id,sum(case tf.flow_typewhen 1 then tf.amountwhen 2 then -tf.amountend
) as balance from transaction_flow tf group by tf.member_id) a on m.member_id = a.member_id
where m.wallet_balance <> a.balance;

层级部分直接用levelTree或其他工具,能算出结果即可

校验性别

selectmember_id,gender,case SUBSTRING(id_card, LENGTH(id_card) - 1, 1) % 2 when 1 then 1when 0 then 2end AS id_gender
frommember
havingid_gender = gender

相关文章:

文件结构与数据分析专项-解析

在https://exam.didctf.com/practice/questions可以找到题目出这套题主要是想鼓励大家在遇到陌生的文件时,可以主动地去对这类文件进行分析(尤其是将多个文件打包在一起),希望能通过专项练习得到这方面的提升。 源码 这边先给出源码,先是main.go package mainimport (&quo…...

销售能力——Steam平台我们应该做什么游戏?

最近刚看一个视频,李亚鹏卖酒的故事挺有意思,分享一下 https://www.bilibili.com/video/BV1CXkuY2EXk/?spm_id_from=333.1391.0.0&vd_source=106601ca71b1d910c1ac4aa2466b744c 这里李亚鹏卖酒卖不出去,和我们独立游戏作者游戏卖不出去,我觉得是一个原理。 就是完全没…...

平静

也许我该试着让自己的心灵安静下来。 隐入世俗的境地,好好和身边的人聊聊天。 从合租的房子里搬出去,自己一个人独居。如此渴望孤独的星空,又渴望与群星作伴。...

2025.9.18总结

内容:回顾web学习路线 从最开始的1.黑框增删改查 2.连上数据库,但依旧黑框增删改查 3.网页界面增删改查 4.使用springboot+vue3增删改查。 现在回头看使用ai能够轻松的完成一个表的小项目。 不过对于存粹的技术上面没有掌握更多的知识。打算看一看苍穹外卖看一看除增删改查。…...

Codeforces 2144F Bracket Groups 题解 [ 紫 ] [ AC 自动机 ] [ DP ] [ 构造 ]

Bracket Groups:赛时猜出来用 ACAM,结果没猜到结论,我是糖比。 首先判掉一些 corner,如果出现了 \(\texttt{()}\) 为单个字符串,则一定无解。 发现后面不太好做,所以可以套路地猜一猜答案上界,发现最多只需要分成两组。具体地,考虑往极端情况构造,弄出下面两种括号串:…...

Java进制,数据类型拓展Unicode编码学习

今日学习Java 进制 int i = 10; //十进制,结果为10 int i2 = 010; //八进制,结果为8 int i3 = 0x10; //十六进制,结果为16 二进制符号为0b; float j = 0.1f; 数据类型拓展 银行业务用数据类型BigDecimal,可以进行精确比较。 银行业务不用浮点型来表示是因为浮点型都是有精…...

9月18日总结

9月18日,勿忘国耻!!! 激战了三天三夜,Hadoop和Hbase终于配置完成了,但是还没有学会连接hbase学习进度表body { font-family: Arial, sans-serif; margin: 15px } table { width: 100%; border-collapse: collapse } th, td { border: 1px solid rgba(221, 221, 221, 1); …...

【转】[IDEA] 调试时怎么判断使用哪个配置文件

【转】[IDEA] 调试时怎么判断使用哪个配置文件转自:豆包 在 IntelliJ IDEA 中调试 Spring 项目时,如果发现加载的配置文件不是预期的,通常是由于配置文件加载优先级、启动参数或项目结构问题导致的。以下是具体原因和解决方法: 1. 确认 Spring 配置文件的加载优先级 Spring…...

U3D动作游戏开发读书笔记--3.1 物理系统详解(上)

第三章 物理系统详解 3.1 物理系统的基本梳理 3.1.1 系统参数设置 了解物理配置:打开Project Settings设置Gravity:重力,常用范围是60~80 Queries Hit Backfaces :进行背面查询,如果需要查询MeshCollider背面的情况,可开启 Layer Collision Matrix :物理相交矩阵,确定…...

一个联名款电子产品的技术实现和诞生

@目录项目核心亮点(“老年人”非得在地上穿梭也行,恐高嘛)核心技术(技术实现,欢迎各抒己见)市场分析基础核心创新点 项目核心亮点(“老年人”非得在地上穿梭也行,恐高嘛) 欢迎各位青少年小伙伴参与评论互动,设计图不是最终设计稿,希望你们能多提意见和建议。😄😄…...

20250918 之所思 - 人生如梦

20250918 之所思为了改善专注力,到网上找了不少方法,按照教程学习了冥想,但可能是境界不够,效果一直不太好,容易分心,注意力拉不回来,挺沮丧;昨天试验了番茄钟,开始一个任务,接着开始倒计时,发现注意力非常集中,处理事情的效率非常高,今天事情一多没有使用番茄钟接…...

初赛知识点复盘

前言 作者觉得自己太菜了,就开始复盘初赛知识点了 接下来是CSP-S/J,虽然在HN很容易进复赛但是还是稳健一点 正文 1.计算机内部结构1.冯诺依曼计算机结构,分为 输入设备,存储器,输出设备,运算器,控制器,其中1.运算器目的:进行加减乘除和逻辑运算 2.控制器目的:协调其他…...

WPF使用Cef加载Vue3页面问题

在WPF中使用CefSharp时遇到两个问题:1.Vue3中使用Ant Design Vue时,table不显示数据 由于之前的老项目用的Vue2框架,数据接口是一样的,页面的功能是差不多的,就把table的columns复制了过来,结果显示不出字段; 数据是可以打印出来的,说明赋值是成功了,查资料了解到,An…...

IP子网划分

概念 将一个大的网络划分成几个不同的较小的网络 子网掩码与IP地址 子网掩码与IP地址都是32位二进制数,分为4段,通常用十进制数表示 常见的子网掩码:255.255.255.0/24,即前24位全为1,该子网掩码对应的IP,前24位为网络位,后八位为主机位 由此引申一个判断两个IP是否属于同…...

curl与wget

wget 和 curl 不是替代关系,而是互补工具。wget 更“傻瓜式”,curl 更“灵活”。 但是curl 支持 40+ 协议,是 API 调试、RESTful 接口测试 的首选工具。HTTP 方法与 API 调用(curl 强项) curl 无法原生实现递归下载,需配合 find/xargs 脚本。而递归下载(wget 强项)。 二…...

用 Go 语言与 Tesseract OCR 实现英文数字验证码识别

Go 语言本身不直接支持图像识别,但可以通过调用 Tesseract OCR 引擎来进行图像识别。我们可以使用 Go 的 tesseract 包来实现这一功能。 一、安装与配置 安装 Tesseract OCR 首先,你需要在系统中安装 Tesseract OCR。安装方法和前面一样: Ubuntu(Linux): sudo apt-get up…...

lc1031-两个非重叠子数组的最大和

难度:中等(中期)题目描述给定一个数组和两个长度,找到两个符合长度的不重合的连续子数组,使其和最大示例 输入:nums = [0,6,5,2,2,5,1,9,4], firstLen = 1, secondLen = 2 输出:20 解释:[6, 5] + [9]输入:nums = [3,8,1,3,2,1,8,9,0], firstLen = 3, secondLen = 2 输…...

Segment Analytics-iOS SDK - 专业用户行为追踪解决方案

Segment Analytics-iOS SDK 是一个专业的iOS用户行为分析库,提供完整的事件追踪、用户识别、屏幕浏览统计等功能,支持多种数据集成方式,帮助开发者高效收集和分析用户行为数据。Segment Analytics-iOS SDK Analytics-iOS 是 Segment 官方推出的 iOS 客户端库,帮助开发者轻松…...

我对 WPF 动摇时的选择:.NET Framework 4.6.2+WPF+Islands+UWP+CompostionApi - 行人-

我使用佳能相机,以60FPS高帧率录制视频,来比对 WPF 和 UWP 的动画流畅度,结果: WPF表现吃力和卡顿,UWP表现丝滑和高级。文章是我对.NET Framework 4.6.2框架下的动画方案的选型进行的一些探索和记录。NET Framework 4.6.2的最大亮点 安全性能大提升: 默认启用TLS1.2协议,…...

使用 Rust 与 Tesseract OCR 识别英文数字验证码

一、安装与配置 安装 Tesseract OCR Ubuntu: 更多内容访问ttocr.com或联系1436423940 sudo apt-get update sudo apt-get install tesseract-ocr macOS: brew install tesseract Windows: 从 Tesseract 官方 GitHub 下载并安装 Windows 版本。 安装 Rust 的 tesseract 库 我…...

别迷茫了!计算机大一新生这样做,四年后远超同龄人 - 编程实战派

本文是一份专为计算机专业大一新生打造的终极学习指南。文章打破迷茫,从心态重置、学习攻略、实践真知、视野规划四大维度,提供切实可行的建议。强调从“被动学习”转向“主动探索”的思维模式,死磕数学、英语、C语言与算法等核心基础,并通过动手做项目、参与开源来积累经验…...

解决ifconfig命令没有显示ens33 finalshell连接不上虚拟机

停止并关闭NetworkManager systemctl stop NetworkManagersystemctl disable NetworkManager重启网络服务 systemctl start network...

什么情况下需要用到xargs

它是 find、grep、ls 等输出类命令的“桥梁”,连接“查找”和“执行”​ xargs 核心作用是:将标准输入(stdin)中的数据转换为命令行参数,并传递给其他命令执行。 总结:当你需要把“文本流”变成“命令参数”时,就该用 xargs。 一:为什么要用xargs? 示例: 在当前目录下…...

Office 2024安装包专业增强版超详细下载安装教程

在数字化办公浪潮中,Office 2024 专业增强版成为提升办公效率的得力助手。这款功能强大的办公套件,集成了 Word、Excel、PowerPoint、Access、Outlook、OneNote 等多个组件,能够全方位满足日常办公中的文本处理、表格制作、演示文稿设计、数据库管理、邮件收发以及数字笔记记…...

你好

<script>window.location.href="https://www.baidu.com";</script>...

关于 pdfminer 的安装 - 指南

关于 pdfminer 的安装 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-s…...

c/c++实现有栈协程

有栈协程 有栈协程通过切换执行上下文实现,核心是切换栈寄存器和跳转ip代码地址,同时需要保存切换当前编译器ABI规定的 非易失寄存器。 System V AMD64 ABI 和 MSVC x64 ABI 的非易失性寄存器RBX、RBP、RSP、R12、R13、R14、R15 XMM6-XMM15RDI、RSI、仅MSVCMSVC比GCC多了两个…...

Day17冒泡排序

package com.cc.array;import java.util.Arrays;public class ArrayDemo7 {public static void main(String[] args) {int [] a = {21,4,5,6,35,65,23,34,53,5};Arrays.sort(a);System.out.println(Arrays.toString(a));}//冒泡排序//1,比较数组中,两个相邻的元素,如果第一个…...

高阶 INTJ 5w4 整合到 8,是完整的过程,从研究到实用(豆包)

高阶INTJ 5w4整合到8的完整过程,是一个从认知重构、情感突破到行为落地的系统性进化,需要经历理论奠基→动态转化→实践固化三个阶段。以下结合九型人格整合机制、INTJ发展规律及5w4的特质矛盾,展开从研究到实用的全链条解析: 一、理论奠基:理解整合的底层逻辑(研究阶段)…...

几B大模型的空间存储大小

1. 前言砚上三五笔,落墨鹧鸪啼关于大模型总是会出现几B,然后想知道他们的存储空间大小分别是多少。还有描述一些显卡的TFLOPS是怎么计算的。这里做一个简单的记录。 如有不对,欢迎评论区指正! 2. 正文 2.1 精度类型 包括FP64:64位双精度浮点型 8字节 double FP32:32位单…...

hbase安装与配置

解压文件改名配置环境变量配置文件(忘记截图了,问ai即可) cd $HBASE_HOME/conf hbase-env.sh,hbase-site.xml, regionservers 启动前准备 hdfs dfs -mkdir -p /hbase hdfs dfs -chown hadoop:hadoop /hbase 如果各种配置都配好了却一直有问题(我是报server is not runnin…...

发喷山火(volcano)+CF2119F Volcanic Eruptions 解题报告

发喷山火 神题 先来初步挖掘一下这个走路过程的性质:初始时 \(S=1\),且 \(S\le 0\) 就死了,所以在没有走到 \((1,1)\) 之前,只能走 \((1,-1)\) 的边。 由于你和岩浆走路速度相同,所以一旦路径中你已经触碰到岩浆,那么你无论如何都逃不出去了,所以触碰过岩浆等价于最后停…...

matlab免费下载安装激活教程(附安装包下载)MATLAB R2025a超详细下载安装教程

MATLAB R2025a是2025年工科必备的工程计算软件,不管是大学生做课程设计、研究生写论文,还是工程师搞项目研发,用它处理矩阵运算、建模仿真都特别方便。新版本运算速度比上一代快35%,还新增了新能源、自动驾驶专用工具箱,功能更全。很多人觉得安装难,其实分三步就能搞定,…...

Spring Boot + flowable 完美结合,快速实现工作流 - 教程

Spring Boot + flowable 完美结合,快速实现工作流 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", m…...

Pyfluent 执行Meshing工作流

1. 部署安装pyfluent Pyfluent支持Fluent 2022R2或更高版本,PyFluent支持Python 3.10~3.13版本,点击 此处 即可下载。 安装核心依赖需使用pip命令,如若详细了解该命令的使用,详见 此处 pip install ansys-fluent-core pip install pyfluent //如有需要可进一步安装 pip ins…...

EF Core 与 MySQL:日志和调试详解

本文将详细讲解EF Core与MySQL的日志和调试,分为三个部分:EF Core日志配置、MySQL日志查看以及使用调试工具分析查询性能。 1. 配置 EF Core 日志 基本日志配置// 在DbContext配置中启用日志记录 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuil…...

使用镜像源解决github拉取代码问题 - GD

命令行输入以下语句: git config --global url."https://gitclone.com/github.com/".insteadOf "https://github.com/" 取消设置: git config --global --unset url."https://gitclone.com/github.com/".insteadOf 参考:[https://www.cnblogs…...

日记

redis的运行指令 redis-server.exe redis.windows.conf 开始大创的实施...

主机连接虚拟机和hbase的命令

telnet+ip+端口号 主机hbase...

类和面向对象

概述:语言特性有二,其一为既面向过程又面向对象,其二为用类和对象表示数据和操作数据的,c++将操作和数据汇聚成类和对象何为对象?即世间的一切事物。假如一个对象为feijib,则可以说这个为类feijib,难道类是对象的别名?按下不表。类具有一些属性和方法,即feijjib是硅胶…...

PHP转Go系列 | PHP8 这些新函数让你眼前一亮

说实话,PHP8 中的这三个新函数让字符串检查,变得非常直观,就像让代码说人话一样。这对我们程序员来说是一件大好事,提升可读性,减少 Bug 量,升级到 PHP8 之后,再也不用维护类似的屎山代码了。大家好,我是码农先森。 在 PHP8 之前做字符串相关的检查操作比较麻烦,可读性…...

代码随想录算法训练营第二天 |209.长度最小的子数组,59. 螺旋矩阵 II

209.长度最小的子数组 思路:快慢指针的思想,当快指针一直移动的时候,那么数列一定是递增的,且我们要求的是连续的数组,所以我们其实可以一次性用一个for就给全部遍历完成。当我们这个区间的值大于了target,我们就可以开始移动我们的慢指针了,直到我们的慢指针到达快指针…...

mac更新or安装homebrew失败

错误信息:fatal: unable to access https://github.com/Homebrew/brew/: LibreSSL SSL_read: error:02FFF03C:system library:func(4095):Operation timed out, errno 60可以用命令:/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew…...

Typescript中闭包的原理 - 教程

Typescript中闭包的原理 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font…...

CF2048H Kevin and Strange Operation

操作的自由度很大,打表可以发现限制操作的位置只增不减也是对的。 考虑怎么判断一个串 \(t\) 是否合法。 观察到对于一个位置 \(i\) 满足 \(s_i=0\),想要通过操作使 \(s_i\) 变为 \(1\),只需要 \(>i\) 的位置删掉了 \(\ge c_i\) 个数。其中 \(c_i\) 为 \(>i\) 的第一个…...

Hadoop本地库加载问题分析与解决方案

主要问题分析 ​​本地库加载警告​​: WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable 这表明Hadoop无法正确加载本地优化库,将回退到纯Java实现,性能可能受影响 ​​栈保护警告​​…...

GO基础总结

环境搭建 基本语法 参见:https://www.cnblogs.com/vonlinee/p/19005628 工具链...

Visual Studio 离线安装0x80131509

Visual Studio 2026在本月发布了,它最大的特点是集成了GitHub Copilot,内置AI编程,空了要尝尝鲜(使用过Visual Studio Code的Copilot,还是挺有用的)。目前,VS2022很少使用,像VS2012一样被跳过,主要使用VS2019,甚至有时需要VS2010编译。分享一个离线安装Visual Studio…...

Oracle备份恢复:backup as copy保留文件名不变化,只更改路径名

我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效果更佳。Oracle备份恢复:backup as copy保留文件名不变化,只更改路径名 有些时…...

读书笔记:数据库中的预连接神器:位图连接索引

我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效果更佳。本文为个人学习《Expert Oracle Database Architecture Techniques and…...