OBD数据分析(一)

对文件中的字符串进行排序、去掉重复的字符串并输出到另一个文件中

  • 您好,请多指教
    • 小准备
    • 删除Timestamp及其后的内容输入到一个txt文件中
    • 找到指定的id的内容,并输出到文件中
    • 将数据进行排序,删除重复的数据输出到文件中
    • 完整版代码

您好,请多指教

这是我第一次写博客,在文案和代码方面都还有很多的不足,请多包涵,可以的话,请多指教~~

本次主要是对OBD采集并保存到txt文件中的数据进行分析(C语言),比如在DoS攻击下采集的数据,数据大概是下面这样子的:
OBD数据分析(一)_第1张图片
需要做的是:

  1. 将不同的数据导入到不同的文件里,并以如id00000000.txt里面装的就是id为0000000的不同数据。
  2. 将每个txt文件中的数据按从小到大排序并删除内容重复的数据,以便于进行数据分析。

我们现在开始啦~

小准备

将数据进行分片输入

  1. 如以下数据:
    一条数据的具体内容
    数据用结构体进行封装,如下:
typedef struct
{
	//基本是按一个不包含空格的字符串为一段的 
	char Timestamp[20];//第一片数据“Timestamp” 
	char timestamp[20];//第二片数据为Timestamp的内容 
	char ID[5];//第三片数据为“ID:” 
	char id[5];//第四片数据为ID的前一段内容,四个字符 
	char id2[5];//第五片数据为ID的后一段内容,三个字符 
	char DLC[5];//第六片数据为“DLC:” 
	char dlc[15];//第七片数据为DLC的内容 
	char Data[50];//第八片数据为Data的具体内容 
}data;
  1. 写代码前的一些基本的定义
	data table;//定义结构体 
	data tmp;//定义中间结构体,在进行数据排序时用到 
	data tablepx[9000];//排序时用的结构体 
	char f[] = {"ID"};//数据是两个两个一小段的,所以用gets()输入 
	char fd[] = {"DLC"};
	char *p; //找到ID时用到的指针 
	char *pd; //找到DLC时用到的指针 
	char buf[999];//定义缓冲区,用于暂时存储数据 
	FILE *fp;
	FILE *fout;
	int table_len = 0, i=0, j;	
	FILE *fp1;//定义中间文件 
	
	char a[] = "F:\\id1.txt";//DoS_attack_dataset整理后格式标准的数据 
	char b[] = "F:\\1.txt";//b存储删掉了"Timestamp"数据 
	char e[] = "0153";//要挑出来放在另外一个txt文件中的id的前半段 
	char c[] = "F:\\id0153.txt";//因为id的后半段几乎是000,所以先暂定全部后部分为000 
	char d[] = "F:\\id0153000.txt";//排序并且删除了重复的数据 
	

删除Timestamp及其后的内容输入到一个txt文件中

在排序过程中,因为Data的内容中间包含了空格,所以用到了strstr方法来找到其首位置

在之前的尝试中,将table定义为了字符串,所以在下面代码的运行过程中出现了在读数据方面的错误,现已经通过加入组件文件来储存数据解决了这个问题


	fp = fopen(a,"r+");//打开文件 
	if(fp == NULL)
	{
		printf("read error!\n");
		return 0;
	}
	while(fgets(buf, 100, fp) != NULL)
	{
		sscanf(buf,"%s%s%s%s%s%s%s",&table.Timestamp,&table.timestamp, &table.ID,&table.id,&table.id2,&table.DLC,&table.dlc);
		p=strstr(buf,f);//找到“ID”所在的位置 
		p=p+4;//找到id内容开始的位置 
		i++;//行数 
		printf("%d\n",i);
		fp1 = fopen(b, "a+");
		if (fp1==0) 
		{ 
			printf("can't open file\n");
			return 0;
		}
		fprintf(fp1,"%s",p);//输出id及其的内容到txt文件中 
		fclose(fp1);//关闭文件 
	}
	fclose(fp);

结果产生内容如下的文件(删除了Timestamp后的一条消息的具体内容)
OBD数据分析(一)_第2张图片

找到指定的id的内容,并输出到文件中

	fp1 = fopen(b, "r+");
	fout = fopen(c,"a+");	
	while(fgets(buf, 100, fp1) != NULL) 
	{
		sscanf(buf,"%s%s%s%s",&table.id,&table.id2,&table.DLC,&table.dlc);
		pd=strstr(buf,fd);//指针指到“DLC”的位置 
		pd=pd+10;//指针指到Data数据的开端部分 
		strcpy(table.Data,pd);//将数据赋值给结构体的Data 
		printf("%s",table.Data);
		if(strcmp(table.id, e) == 0)//对比id是不是要找的 
		{
			printf("%s \n",table.id);
			fprintf(fout,"%s %s  %s  %s  %s",table.id,table.id2,table.DLC,table.dlc,table.Data);//将数据输出到文件中 
		}
	}
	fclose(fp1);
	fclose(fout);

产生内容如下的文件(id前四位为0153的数据)
OBD数据分析(一)_第3张图片

将数据进行排序,删除重复的数据输出到文件中

将缓存区的数据赋给数组,以便之后对Data的排序,无奈字符串长度有限度,故此处定义字符串长度为9000,所以只能处理9000条数据

	//打印ID和DLC 	
	fp = fopen(c,"r+");
	fout = fopen(d,"w+");
	if(fp == NULL)
	{
		printf("read error!\n");
		return 0;
	}
	while(fgets(buf, 100, fp) != NULL)
	{
		sscanf(buf,"%s%s%s%s",&tablepx[table_len].id,&tablepx[table_len].id2,&tablepx[table_len].DLC,&tablepx[table_len].dlc);
		p=strstr(buf,fd);
		p=p+10;
		strcpy(tablepx[table_len].Data,p);
		table_len++;
		printf("%d\n",table_len); 
	} 
	//Data排序 
	for(j=0; j<(table_len-1); j++)
	{
		for(i=0; i<(table_len-1-j);i++)
		{
			if(strcmp(tablepx[i].Data, tablepx[i+1].Data) > 0)
			{
				tmp = tablepx[i];
				tablepx[i] = tablepx[i+1];
				tablepx[i+1] = tmp;
			}
		}
	}
	//打印不重复的Data 
	for(i=0;i<table_len;i++)
	{
		if(strcmp(tablepx[i].Data, tablepx[i+1].Data) != 0)
		{
			printf("%s %s %s %s %s\n",tablepx[i].id,tablepx[i].id2,tablepx[i].DLC,tablepx[i].dlc,tablepx[i].Data);
			fprintf(fout,"%s %s  %s  %s  %s",tablepx[i].id,tablepx[i].id2,tablepx[i].DLC,tablepx[i].dlc,tablepx[i].Data);
		}
	}
	fclose(fp);
	fclose(fout);

产生的txt文件内容如下(删除了重复值并且排序后的id前四位为0153的数据)
OBD数据分析(一)_第4张图片

完整版代码

#include <stdio.h>
#include <string.h>
typedef struct
{
	//基本是按一个不包含空格的字符串为一段的 
	char Timestamp[20];//第一片数据“Timestamp” 
	char timestamp[20];//第二片数据为Timestamp的内容 
	char ID[5];//第三片数据为“ID:” 
	char id[5];//第四片数据为ID的前一段内容,四个字符 
	char id2[5];//第五片数据为ID的后一段内容,三个字符 
	char DLC[5];//第六片数据为“DLC:” 
	char dlc[15];//第七片数据为DLC的内容 
	char Data[50];//第八片数据为Data的具体内容 
}data;

int main()
{
	data table;//定义结构体 
	data tmp;//定义中间结构体,在进行数据排序时用到 
	data tablepx[9000];//排序时用的结构体 
	char f[] = {"ID"};//数据是两个两个一小段的,所以用gets()输入 
	char fd[] = {"DLC"};
	char *p; //找到ID时用到的指针 
	char *pd; //找到DLC时用到的指针 
	char buf[999];//定义缓冲区,用于暂时存储数据 
	FILE *fp;
	FILE *fout;
	int table_len = 0, i=0, j;	
	FILE *fp1;//定义中间文件 
	
	char a[] = "F:\\id1.txt";//DoS_attack_dataset整理后格式标准的数据 
	char b[] = "F:\\1.txt";//b存储删掉了"Timestamp"数据 
	char e[] = "0153";//要挑出来放在另外一个txt文件中的id的前半段 
	char c[] = "F:\\id0153.txt";//因为id的后半段几乎是000,所以先暂定为000 
	char d[] = "F:\\id0153000.txt";//排序并且删除了重复的数据 
			
	fp = fopen(a,"r+");//打开文件 
	if(fp == NULL)
	{
		printf("read error!\n");
		return 0;
	}
	while(fgets(buf, 100, fp) != NULL)
	{
		sscanf(buf,"%s%s%s%s%s%s%s",&table.Timestamp,&table.timestamp, &table.ID,&table.id,&table.id2,&table.DLC,&table.dlc);
		p=strstr(buf,f);//找到“ID”所在的位置 
		p=p+4;//找到id内容开始的位置 
		i++;//行数 
		printf("%d\n",i);
		fp1 = fopen(b, "a+");
		if (fp1==0) 
		{ 
			printf("can't open file\n");
			return 0;
		}
		fprintf(fp1,"%s",p);//输出id及其的内容到txt文件中 
		fclose(fp1);//关闭文件 
	}
	fclose(fp);

	fp1 = fopen(b, "r+");
	fout = fopen(c,"a+");	
	while(fgets(buf, 100, fp1) != NULL) 
	{
		sscanf(buf,"%s%s%s%s",&table.id,&table.id2,&table.DLC,&table.dlc);
		pd=strstr(buf,fd);//指针指到“DLC”的位置 
		pd=pd+10;//指针指到Data数据的开端部分 
		strcpy(table.Data,pd);//将数据赋值给结构体的Data 
		printf("%s",table.Data);
		if(strcmp(table.id, e) == 0)//对比id是不是要找的 
		{
			printf("%s \n",table.id);
			fprintf(fout,"%s %s  %s  %s  %s",table.id,table.id2,table.DLC,table.dlc,table.Data);//将数据输出到文件中 
		}
	}
	fclose(fp1); 
	fclose(fout);
	
	//打印ID和DLC 	
	fp = fopen(c,"r+");
	fout = fopen(d,"w+");
	if(fp == NULL)
	{
		printf("read error!\n");
		return 0;
	}
	while(fgets(buf, 100, fp) != NULL)
	{
		sscanf(buf,"%s%s%s%s",&tablepx[table_len].id,&tablepx[table_len].id2,&tablepx[table_len].DLC,&tablepx[table_len].dlc);
		p=strstr(buf,fd);
		p=p+10;
		strcpy(tablepx[table_len].Data,p);
		table_len++;
		printf("%d\n",table_len); 
	} 
	//Data排序 
	for(j=0; j<(table_len-1); j++)
	{
		for(i=0; i<(table_len-1-j);i++)
		{
			if(strcmp(tablepx[i].Data, tablepx[i+1].Data) > 0)
			{
				tmp = tablepx[i];
				tablepx[i] = tablepx[i+1];
				tablepx[i+1] = tmp;
			}
		}
	}
	//打印不重复的Data 
	for(i=0;i<table_len;i++)
	{
		if(strcmp(tablepx[i].Data, tablepx[i+1].Data) != 0)
		{
			printf("%s %s %s %s %s\n",tablepx[i].id,tablepx[i].id2,tablepx[i].DLC,tablepx[i].dlc,tablepx[i].Data);
			fprintf(fout,"%s %s  %s  %s  %s",tablepx[i].id,tablepx[i].id2,tablepx[i].DLC,tablepx[i].dlc,tablepx[i].Data);
		}
	}
	fclose(fp);
	fclose(fout);
	
	//remove(c);//删除中间的临时文件 
	
	return 0;
 } 

最后会生成三个文件,如下(第一个是前提文件)
‘程序执行完成后生成的txt文件’

啦啦啦,这部分就暂时结束啦,欢迎提建议呀~~

你可能感兴趣的:(OBD数据分析(一))