【毕设扫描器】【参数Fuzz】第一篇:数据的定义、读取和装配(爬虫数据和Payload数据)

本文主要是介绍【毕设扫描器】【参数Fuzz】第一篇:数据的定义、读取和装配(爬虫数据和Payload数据),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 字典文件的数据结构
    • 读取嵌套的 Json 数据
        • 读取值为基本数据类型的Json文件
        • 读取值为数组的Json数据
        • 读取值为字典的Json文件
        • 读取包含两个层级键名的Json文件
    • 准备数据阶段
        • 修改爬虫保存结果(结合报错和实际情况未修改代码,可忽略)
        • 从 Json 文件读取需要的爬虫数据
        • 读取 paramsFuzz.json 文件
    • 装配数据阶段
        • 配置请求对象 req
        • 保存传递动态参数的 Url 信息
        • 装配数据
            • 第一步
            • 第二步
            • 第三四五步
    • 执行阶段
    • 接收结果并验证阶段

字典文件的数据结构

在项目根目录创建 fuzzDicts 目录,创建 fuzzDicts/params.json,用于测试参数。(使用 json 是因为常见/易读/复用性强)

参数测试Payload格式:不同的漏洞类型、漏洞类型下不同的软件系统、对应Payload。

一级数据是漏洞类型,如 SQLI、XSS等,数据结构是字典格式。(添加字段 description 描述payload,不需要专门使用一个字段进行分类。该部分是在读取 Json 文件时进行的修改)

二级数据是漏洞类型的下一级数据,可能需要根据不同软件类型选择 Payload,所以也要使用字典格式。二级数据如果不分软件类型,则定义键名为 universal(还要单独输入一个字段,而大多数情况都不知道软件类型,还是要枚举测试所有Payload,所以该字段不是很有必要)

二级数据是Payload,根据不同Payload需要选择不同的响应判断,如时间延迟注入的响应时间、响应内容中的关键字,所以使用字典格式。(Payload直接作为污染参数数据的键名即可)(实际读取 Json 文件时做出的优化)

一级数据是一个键 data,其键值是数据类型,用于存储 payload 的字典信息。

二级数据是最底层的数据,注入参数可能有很多、响应时间是整数、关键词是字符串等,所以根据实际需要分别使用 List、Int、String等数据类型。

未考虑的场景问题

  • 根据比较不同Payload下返回的响应信息来判断漏洞是否存在。

排版如下。

{"data":[{"description": "SQLI-001: MySQL-数字型延迟注入","payload": "/**/and/**/sleep(5)","time": 5,"keyword": ""},{"description": "SQLI-002: MySQL-字符型延迟注入","payload": "'/**/and/**/sleep(5)--+","time": 5,"keyword": ""},{"description": "SQLI-003: MySQL-字符型延迟注入","payload": "\"/**/and/**/sleep(5)--+","time": 5,"keyword": ""},{"description": "SQLI-004: MySQL-报错注入","payload": "'\"+,","keyword": "You have an error in your SQL syntax"},{"description": "XSS-001: 跨站脚本攻击漏洞""payload": "<script>alert(/xss/)</script>","keyword": "xxx"}]}

读取嵌套的 Json 数据

读取值为基本数据类型的Json文件

这里的单层是指,Json数据的值是基本数据类型,不是列表、字典等数据结构。

创建 test.json 文件,文件内容如下。

{"name": "pumpkin","date": "2022-04-05"
}

查找网上文章 Go 对象序列化 等,编写读取Json文件代码。

  • 读取配置文件的字节数据:bytesJSON, err := ioutil.ReadFile(“example.json”)

  • go 内置对 json 数据的处理包是 encoding/json

  • 把字节数据解析成Json编码数据:json.Unmarshal

  • 接收Json数据:需要事先定义一个结构体

成功运行解析的代码和打印结果如下。

/* 打印结果pumpkin2022-04-05
*///定义配置文件解析后的结构
type Test struct {Name	string 	`json:"name"`Date	string `json:"date"`
}func main() {var test Testbytes, err := ioutil.ReadFile("./test.json")if err != nil {fmt.Println("读取json文件失败", err)return}err = json.Unmarshal(bytes, &test)if err != nil {fmt.Println("解析数据失败", err)return}fmt.Println(test.Name)fmt.Println(test.Date)
读取值为数组的Json数据

test.json 配置文件的内容如下。

此时使用上一小节读取基本数据类型的代码,json.Unmarshal(bytes, &test) 会报错并退出程序,无法把数组结构解析成 Go 结构体的 string 类型:
解析数据失败 json: cannot unmarshal array into Go struct field Test.name of type string

{"name": ["pumpkin", "watermelon"],"date": "2022-04-05"
}

修改结构体的参数类型为字符串数组:[]string。运行成功且打印结果如下。

/*	打印结果[pumpkin watermelon]2022-04-05
*/
//定义配置文件解析后的结构
type Test struct {Name	[]string 	`json:"name"`Date	string 		`json:"date"`
}
读取值为字典的Json文件

参考文章 golang 数据三 (字典),golang基本数据结构Map也叫字典,字典的声明格式是:map[KeyType]ValueType

此时 test.json 配置文件的内容如下。

{"name": ["pumpkin", "watermelon"],"date": "2022-04-05""sex":{"man":1,"woman":0}
}

定义接收 Json 数据的结构体如下,成功读取并打印 Json 数据内容。

//定义配置文件解析后的结构
type Test struct {Name	[]string 		`json:"name"`Date	string 			`json:"date"`Sex 	map[string]int	`json:"sex"`
}// main()函数中的操作代码
func main() {var test Testbytes, err := ioutil.ReadFile("./test.json")if err != nil {fmt.Println("读取json文件失败", err)return}err = json.Unmarshal(bytes, &test)if err != nil {fmt.Println("解析数据失败", err)return}fmt.Println(test.Name)fmt.Println(test.Date)fmt.Println("man: ", test.Sex["man"])fmt.Println("woman: ", test.Sex["woman"])
}
读取包含两个层级键名的Json文件

此时 test.json 配置文件的内容如下。

{"req_list": [{"url": "http://127.0.0.1/sqli-labs-master/Less-1/?id=1","method": "GET","headers": {"Spider-Name": "crawlergo","User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.0 Safari/537.36"},"data": "","source": "Target"}],"all_req_list": [{"url": "http://127.0.0.1/sqli-labs-master/Less-1/?id=1","method": "GET","headers": {"Spider-Name": "crawlergo","User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.0 Safari/537.36"},"data": "","source": "Target"}],"all_domain_list": ["127.0.0.1"],"sub_domain_list": ["127.0.0.1"]

尝试定义 req_list 的值为数组 array,json.Unmarshal() 函数报错:解析数据失败 json: cannot unmarshal object into Go struct field Crawler.req_list of type string。

type Crawler struct {ReqList         []string `json:"req_list"`AllReqList      []string `json:"all_req_list"`AllDomainList 	[]string `json:"all_domain_list"`SubDomainList 	[]string `json:"sub_domain_list"`
}

数组的元素值类型应该是字典 map,尝试定义如下结构体,仍然是相同的报错信息。

type Crawler struct {ReqList         []map[string]string `json:"req_list"`AllReqList      []map[string]string `json:"all_req_list"`AllDomainList 	[]map[string]string `json:"all_domain_list"`SubDomainList 	[]map[string]string `json:"sub_domain_list"`
}

由于 Json 文件包含不同层级的键名,所以定义结构体的结构也肯定不同,参考文章:Go 解析嵌套 json。

如果 Json 数据有多层键,那么每层键都需要定义一个结构体接收对应的键名,并且定义变量时需要嵌套结构体类型。

查看参考文章编写代码,成功读取嵌套 Json 文件的代码和打印结果如下。

/*	打印结果http://127.0.0.1/sqli-labs-master/Less-1/?id=1GETSpider-Name crawlergoUser-Agent Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.0 Safari/537.36
*/
// 接收第一层 Json 数据
type CrawlerFirst struct {ReqList			[]CrawlerSecond			`json:"req_list"`AllReqList      []CrawlerSecond 		`json:"all_req_list"`AllDomainList 	[]string 				`json:"all_domain_list"`SubDomainList 	[]string 				`json:"sub_domain_list"`
}type CrawlerSecond struct {Url			string						`json:"url"`Method      string 						`json:"method"`Headers 	map[string]string 			`json:"headers"`Data 		string 						`json:"data"`Source 		string						`json:"source"`
}// Test 定义配置文件解析后的结构
type Test struct {Name	[]string 		`json:"name"`Date	string 			`json:"date"`Sex 	map[string]int	`json:"sex"`
}func main() {//var req model.Requestvar crawlerFirst CrawlerFirstbytes, err := ioutil.ReadFile("./debug.json")if err != nil {fmt.Println("读取json文件失败", err)return}err = json.Unmarshal(bytes, &crawlerFirst)if err != nil {fmt.Println("解析数据失败", err)return}for _,req:= range crawlerFirst.ReqList{fmt.Println(req.Url)fmt.Println(req.Method)fmt.Println(req.Data)for key,value:= range req.Headers {fmt.Println(key, value)}}}

准备数据阶段

修改爬虫保存结果(结合报错和实际情况未修改代码,可忽略)

读取爬虫结果的前提是,爬虫结果是我们需要的数据。原项目中把如下 4 种数据保存到一个 Json 文件,我们首先需要分离这些数据,使每种数据分别保存到各自的文件。

type Result struct {ReqList       []Request `json:"req_list"`AllReqList    []Request `json:"all_req_list"`AllDomainList []string  `json:"all_domain_list"`SubDomainList []string  `json:"sub_domain_list"`
}

crawlergo_cmd.go 文件保存结果的相关代码,调试打印 result 变量值发现,此时爬虫结果按照 Result 结构体都已经填充内容。先酱紫,后续对爬虫结果结构体有想法,再另外进行修改。

考虑到报错、以及直接可以读取 Json 文件,不修改代码。

	// 代码 350 行// 输出结果outputResult(result)// 代码 403 行
func outputResult(result *pkg.Result) {// 输出结果if outputMode == "json" {fmt.Println("--[Mission Complete]--")resBytes := getJsonSerialize(result)fmt.Println(string(resBytes))} else if outputMode == "console" {for _, req := range result.ReqList {req.FormatPrint()}}// 写入文件的主要代码if len(outputJsonPath) != 0 {resBytes := getJsonSerialize(result)tools.WriteFile(outputJsonPath, resBytes)}// 修改该部分主要代码为如下内容(不更改代码,直接读取 json 文件)/*注意,1.结构体中的变量名需要开启调试查看、或从其他代码中找到2.序列化结构体的变量时,报错如下。在结构体定义代码中,前两个变量的类型是 []Request,域名变量是 []string考虑到可以直接读取Json文件,不更改代码。cannot use result.ReqList (type []*model.Request) as type *pkg.Result in argument to getJsonSerializecannot use result.AllDomainList (type []string) as type *pkg.Result in argument to getJsonSerialize*/if len(outputJsonPath) != 0 {resBytes1 := getJsonSerialize(result.req_list)resBytes2 := getJsonSerialize(result.all_req_list)resBytes3 := getJsonSerialize(result.all_domain_list)resBytes4 := getJsonSerialize(result.sub_domain_list)tools.WriteFile("req_" + outputJsonPath, resBytes1)tools.WriteFile("all_req_" + outputJsonPath, resBytes2)tools.WriteFile("all_domain_" + outputJsonPath, resBytes3)tools.WriteFile("sub_domain_" + outputJsonPath, resBytes4)}}
从 Json 文件读取需要的爬虫数据

关于嵌套 Json 文件数据的读取,在本文的上一章节《读取嵌套的 Json 数据》已完成了代码的编写和调试。

读取数据的任务完成了,Fuzz 需要用到哪些数据呢?

url
method
headers	// 为了避免被反爬虫限制访问,必须使用合适的请求头
data

读取爬虫Json文件

// 接收第一层 Json 数据
type CrawlerFirst struct {ReqList			[]CrawlerSecond			`json:"req_list"`AllReqList      []CrawlerSecond 		`json:"all_req_list"`AllDomainList 	[]string 				`json:"all_domain_list"`SubDomainList 	[]string 				`json:"sub_domain_list"`
}type CrawlerSecond struct {Url			string						`json:"url"`Method      string 						`json:"method"`Headers 	map[string]string 			`json:"headers"`Data 		string 						`json:"data"`Source 		string						`json:"source"`
}// 封装函数
func read_crawler() CrawlerFirst{var crawlerFirst CrawlerFirstbytes, err := ioutil.ReadFile("./debug.json")if err != nil {fmt.Println("读取json文件失败", err)os.Exit(1)}err = json.Unmarshal(bytes, &crawlerFirst)if err != nil {fmt.Println("解析数据失败", err)os.Exit(1)}return crawlerFirst
}
读取 paramsFuzz.json 文件

读取代码改了又改,总是报错。无奈从基本数据类型开始编写 Json 文件进行读取,然后逐渐嵌套数据并完成读取 Json 数据,最终代码和打印结果如下。

读取的 Json 文件见本文第一章 字典文件的数据结构

/* 打印 sqli 键值的结果
//	/**/and/**/sleep(5)
//	MySQL-数字型延迟注入
//	5//	'/**/and/**/sleep(5)--+
//	MySQL-字符型延迟注入
//	5//	"/**/and/**/sleep(5)--+
//	MySQL-字符型延迟注入
//	5//	'"+,
//	MySQL-报错注入
//	0
//	You have an error in your SQL syntax
*/// 定义配置文件解析后的结构
type ParamsFuzzJson struct {SqlInjection	[]ParamData		`json:"sqli"`Xss				[]ParamData		`json:"xss"`
}type ParamData struct {Payload 	string		`json:"payload"`Description string 		`json:"description"`Time 		int			`json:"time"`Keyword		string		`json:"keyword"`
}func main() {//var req model.Requestvar paramsFuzzJson ParamsFuzzJsonbytes, err := ioutil.ReadFile("./fuzzDicts/paramsFuzz.json")if err != nil {fmt.Println("读取json文件失败", err)// os.Exit(1)return}err = json.Unmarshal(bytes, &paramsFuzzJson)if err != nil {fmt.Println("解析数据失败", err)return//os.Exit(1)}// fmt.Println(paramsFuzzJson.SqlInjection)// 读取 Json 的 sqli 键for _, param:= range paramsFuzzJson.SqlInjection{// for _,param:= range param.key{fmt.Println(param.Payload)fmt.Println(param.Description)fmt.Println(param.Time)fmt.Println(param.Keyword)}}

装配数据阶段

配置请求对象 req

项目文件 crawlergo/pkg/model 定义的请求对象结构体包含 8 个变量,考虑只保留如下 5 个变量,重新在 paramsFuzz.go 文件定义请求对象结构体。

type Request struct {URL             *URLMethod          stringHeaders         map[string]interface{}PostData        stringProxy           string
}

明确参数 Fuzz 的需求

  • 遍历 req_list:爬虫结果中 req_list 键的内容,如果存在Get参数或Post参数则进行 Fuzz
  • 遍历 paramJson 中的每一个键:sqli、xss等
保存传递动态参数的 Url 信息

对于爬虫结果,要筛选出传递动态参数的URl进行参数Fuzz测试。

顺便把传递动态参数的Url保存到新的Json文件,方便人工查看,如下代码把传递动态参数的爬虫结果保存到指定文件 params_debug.json。

// 接收第一层 Json 数据
type CrawlerJson struct {ReqList			[]CrawlerData			`json:"req_list"`AllReqList      []CrawlerData 		`json:"all_req_list"`AllDomainList 	[]string 				`json:"all_domain_list"`SubDomainList 	[]string 				`json:"sub_domain_list"`
}type CrawlerData struct {Url			string						`json:"url"`Method      string 						`json:"method"`Headers 	map[string]string 			`json:"headers"`Data 		string 						`json:"data"`Source 		string						`json:"source"`
}// 调用代码
for _,crawler:= range crawlerReq {outputParamsResult(crawler)
}func outputParamsResult(result CrawlerData) {// 写入的文件名变量,在合并代码时需要调整修改outputJsonPath := "debug.json"// 输出结果if len(outputJsonPath) != 0 {resBytes := getParamsJsonSerialize(result)tools.WriteFile("params_" + outputJsonPath, resBytes)}
}func getParamsJsonSerialize(paramsResult CrawlerData) []byte {resBytes, err := json.Marshal(paramsResult)if err != nil {log.Fatal("Marshal result error")}return resBytes
}
装配数据

算法步骤:

  • 准备数据1:读取爬虫结果,调用爬虫结构体的参数信息
  • 准备数据2:读取参数 Fuzz 字典,调用结构体
  • 筛选:遍历爬虫结构体,通过条件判断找出传递动态参数的Url,根据传参方式分为 Get 和 Post
  • 准备数据3:逐个添加 Payload 到动态参数末尾,如果是 Get 方式则拼接 Url 和参数
  • 装配:把爬虫结构体的信息、以及处理后的动态参数信息,装配到请求对象 req
  • 运行和验证:发送请求,查看响应信息验证漏洞是否存在(运行阶段)
  • 标记去重:如果动态参数测试过了,则加入 Array ,并且在测试动态参数前检查是否在 Array 中(验证阶段)
第一步

读取爬虫结果

// 接收第一层 Json 数据
type CrawlerJson struct {ReqList			[]CrawlerData			`json:"req_list"`AllReqList      []CrawlerData 		`json:"all_req_list"`AllDomainList 	[]string 				`json:"all_domain_list"`SubDomainList 	[]string 				`json:"sub_domain_list"`
}type CrawlerData struct {Url			string						`json:"url"`Method      string 						`json:"method"`Headers 	map[string]string 			`json:"headers"`Data 		string 						`json:"data"`Source 		string						`json:"source"`
}func main() {// 1.读取爬虫结果crawlerReq := read_crawlerReq()}func read_crawlerReq() []CrawlerData{var crawlerJson CrawlerJsonbytes, err := ioutil.ReadFile("./debug.json")if err != nil {fmt.Println("读取json文件失败", err)os.Exit(1)}err = json.Unmarshal(bytes, &crawlerJson)if err != nil {fmt.Println("解析数据失败", err)os.Exit(1)}return crawlerJson.ReqList}
第二步

读取参数 Fuzz 的 payload 文件 paramsFuzz.json

// 定义结构体接收参数 Fuzz 的 Json 数据
type ParamsFuzzJson struct {Data			[]ParamData		`json:"data"`
}type ParamData struct {Description string 		`json:"description"`Payload 	string		`json:"payload"`Time 		int			`json:"time"`Keyword		string		`json:"keyword"`
}func main() {// 1.读取爬虫结果crawlerReq := read_crawlerReq()// 2.读取参数 Fuzz 字典/*	功能说明:读取得到一个数组,数组里的元素是 Payload 字典。可以通过遍历数组来逐个读取装配 Payload。调用说明:每次装配 payload 都要绑定一个 request以便使用 payload 字典的关键字等字段判断漏洞是否存在,以及探测漏洞存在后打印 payload 信息也就是说,遍历 payload 数组,是遍历的第一层*/paramsArray := read_paramsPayload()// 遍历 Json 数据中 data 键的键值数组,用于获取每一个 payload 字典for _, payloadDict := range paramsArray.Data {fmt.Println(payloadDict.Payload)}}func read_paramsPayload() ParamsFuzzJson {var paramsFuzzJson ParamsFuzzJsonbytes, err := ioutil.ReadFile("./fuzzDicts/paramsFuzz.json")if err != nil {fmt.Println("读取json文件失败", err)os.Exit(1)}err = json.Unmarshal(bytes, &paramsFuzzJson)if err != nil {fmt.Println("解析数据失败", err)os.Exit(1)}return paramsFuzzJson
}
第三四五步

第三步筛选,遍历爬虫结构体,通过条件判断找出传递动态参数的Url,根据传参方式分为 Get 和 Post。

第四步准备数据3:逐个添加 Payload 到动态参数末尾,然后对URL或者PostData进行字串替换。

第五步装配:把爬虫结构体的信息、以及处理后的动态参数信息,装配到请求对象 req。

嵌套的比较复杂,这三部分代码可以通过 封装函数进行优化。不过目前更重要的还是发送 req 对象,尤其是以多线程的方式发送请求,需要进一步深入查看 crawlergo 的项目代码。第六步和第七步都是其他阶段的任务,可以查看下一章。

func main() {// 定义 req 对象var reqFuzz Request// 代理字段,需要等合并代码时设置相同的字段// reqFuzz.Proxy = crawler.// 1.读取爬虫结果crawlerReq := read_crawlerReq()// 2.读取参数 Fuzz 字典/*功能说明:读取得到一个数组,数组里的元素是 Payload 字典。可以通过遍历数组来逐个读取装配 Payload。调用说明:每次装配 payload 都要绑定一个 request以便使用 payload 字典的关键字等字段判断漏洞是否存在,以及探测漏洞存在后打印 payload 信息也就是说,遍历 payload 数组,是遍历的第一层*/paramsPayloadArray := read_paramsPayload()//fmt.Println(paramsPayloadArray)// 3.从爬虫结果中筛选传递动态参数的请求for _,crawler:= range crawlerReq {if crawler.Method == "GET" {if strings.Contains(crawler.Url, "?") {// 4.逐个装配payload// 获取 Url 数组urlArray := strings.Split(crawler.Url, "?")// 分离Url中的Get参数// 字符串中不包含&时,并不会报错,而是返回只有一个元素的数组paramsArray := strings.Split(urlArray[1], "&")// 装配payload:直接使用 payload 分别替换参数,比如用 id=1<script>alert(/xss/)</script> 替换 id=1for _, value := range paramsArray {// 4.遍历payload装配到每个Get参数,逐个添加 Payload 到动态参数末尾for _, payloadDict := range paramsPayloadArray.Data {payload := value + payloadDict.Payloadfmt.Println("原数据:" + value)fmt.Println("替换后的数据:" + payload)// 5.设置 req 对象,使用 payload 替换元素值,然后装配所有数据reqFuzz.URL = strings.Replace(crawler.Url, value, payload, 1)reqFuzz.Method = crawler.MethodreqFuzz.Headers = crawler.HeadersreqFuzz.PostData = crawler.Data// 6.发送 req 对象,接收响应信息// 7.根据响应信息、以及payload中的关键字、响应时间等信息验证漏洞,如果存在则打印。over}}// 保存传递动态参数的URL信息到文件:params_JsonPathoutputParamsResult(crawler)}}if crawler.Method == "POST" {// 4.逐个装配Post参数paramsArray := strings.Split(crawler.Data, "&")// 遍历每个Post参数for _, value := range paramsArray {// 4.遍历payload装配到每个Get参数,逐个添加 Payload 到动态参数末尾for _, payloadDict := range paramsPayloadArray.Data {payload := value + payloadDict.Payloadfmt.Println("原数据:" + value)fmt.Println("替换后的数据:" + payload)// 5.设置 req 对象,使用 payload 替换元素值,然后装配所有数据reqFuzz.URL = strings.Replace(crawler.Data, value, payload, 1)reqFuzz.Method = crawler.MethodreqFuzz.Headers = crawler.HeadersreqFuzz.PostData = crawler.Data// 6.发送 req 对象,接收响应信息// 7.根据响应信息、以及payload中的关键字、响应时间等信息验证漏洞,如果存在则打印。over}}outputParamsResult(crawler)}}
}

执行阶段

另开一篇文章进行记录,可以前往博客检索查看。

接收结果并验证阶段

另开一篇文章进行记录,可以前往博客检索查看。

这篇关于【毕设扫描器】【参数Fuzz】第一篇:数据的定义、读取和装配(爬虫数据和Payload数据)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/621798

相关文章

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

MySQL大表数据的分区与分库分表的实现

《MySQL大表数据的分区与分库分表的实现》数据库的分区和分库分表是两种常用的技术方案,本文主要介绍了MySQL大表数据的分区与分库分表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. mysql大表数据的分区1.1 什么是分区?1.2 分区的类型1.3 分区的优点1.4 分

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Redis 中的热点键和数据倾斜示例详解

《Redis中的热点键和数据倾斜示例详解》热点键是指在Redis中被频繁访问的特定键,这些键由于其高访问频率,可能导致Redis服务器的性能问题,尤其是在高并发场景下,本文给大家介绍Redis中的热... 目录Redis 中的热点键和数据倾斜热点键(Hot Key)定义特点应对策略示例数据倾斜(Data S

Python实现将MySQL中所有表的数据都导出为CSV文件并压缩

《Python实现将MySQL中所有表的数据都导出为CSV文件并压缩》这篇文章主要为大家详细介绍了如何使用Python将MySQL数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到... python将mysql数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到另一个

一文带你了解SpringBoot中启动参数的各种用法

《一文带你了解SpringBoot中启动参数的各种用法》在使用SpringBoot开发应用时,我们通常需要根据不同的环境或特定需求调整启动参数,那么,SpringBoot提供了哪些方式来配置这些启动参... 目录一、启动参数的常见传递方式二、通过命令行参数传递启动参数三、使用 application.pro

SpringBoot整合jasypt实现重要数据加密

《SpringBoot整合jasypt实现重要数据加密》Jasypt是一个专注于简化Java加密操作的开源工具,:本文主要介绍详细介绍了如何使用jasypt实现重要数据加密,感兴趣的小伙伴可... 目录jasypt简介 jasypt的优点SpringBoot使用jasypt创建mapper接口配置文件加密

使用Python高效获取网络数据的操作指南

《使用Python高效获取网络数据的操作指南》网络爬虫是一种自动化程序,用于访问和提取网站上的数据,Python是进行网络爬虫开发的理想语言,拥有丰富的库和工具,使得编写和维护爬虫变得简单高效,本文将... 目录网络爬虫的基本概念常用库介绍安装库Requests和BeautifulSoup爬虫开发发送请求解

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码