首页 > 编程语言 >计算机网络中的检验和(checksum)(包括计算文件的检验和附有c++代码)

计算机网络中的检验和(checksum)(包括计算文件的检验和附有c++代码)

时间:2024-07-22 10:30:43浏览次数:14  
标签:value 16 int checksum sum c++ 检验 效验

介绍:
检验和(checksum),在数据处理和数据通信领域中,用于校验目的地一组数据项的和。它通常是以十六进制为数制表示的形式。如果校验和的数值超过十六进制的FF,也就是255. 就要求其补码作为校验和。通常用来在通信中,尤其是远距离通信中保证数据的完整性和准确性。(此引用了检验和的百度百科)

用处:
在计算机网络中的网络层、运输层的IP协议、TCP协议、UDP协议等高层协议,在报文中存在一个校验和的字段,这个字段的作用是:验证报文在传输过程中是否被改动,如果接收方检测到检验和有差错,则TCP段会被直接丢弃。如下图在IP报文中占4字节。

原理:
把要发送的数据看成 16 比特的二进制整数序列,并计算他们的和。若数据字节长度为奇数,则在数据尾部补一个字节的 0 以凑成偶数。

例子:
16 位效验和计算,下图表明一个小的字符串的 16 位效验和的计算。为了计算效验和,发送计算机把每对字符当成 16 位整数处理并计算效验和。如果效验和大于 16 位,那么把进位一起加到最后的效验和中。

主要思想为:
1.打开文件,用一个字符串存下里面内容
2.首先判断字符串长度是否为奇数,若为奇数,后面补一个“0”
3.将字符串里面的字符进行读取,并转化成ASCII码对应。每次读取两个字符,也就是每两个为一组。
4.由于字符要化为十六进制后拼接,那么两位里面的前一位将乘于16的平方(256)
5.每一组的十进制数相加
6.先将相加得到的化为2进制存放在int里面,再进行处理,int型里面有32位,我们分为前16位和后16位,对于溢出的在进行处理

而这是现在网上大多数的做法,我现在只是为了更直观,在4、5、6步进行修改
4.由于字符要化为十六进制后拼接,那么两位里面的前一位将乘于16的平方(256),转化成16进制
5.每一组的16进制数相加
6.相加时,超过了0xFFFF(16位最大值),则进行溢出处理。

c++代码

#include <vector>
#include <sstream>
#include <iomanip>
#include <fstream>

using namespace std;

string to_hex(int value) {
    stringstream ss;
    ss << hex << value;
    return ss.str();
}

string add_hex(string hex1, string hex2) {
    int num1, num2;
    stringstream ss;
    ss << hex << hex1;
    ss >> num1;
    ss.clear();
    ss << hex << hex2;
    ss >> num2;
    int sum = num1 + num2;
    if (sum > 0xFFFF) {
        sum = (sum & 0xFFFF) + 1;  // Add carry to the sum
    }
    stringstream result;
    result << hex << setw(4) << setfill('0') << sum;
    return result.str();
}

string check(string filename) {
    ifstream file(filename);
    if (!file.is_open()) {
        cout << "无法打开文件" << endl;
        exit(0);
    }
    string chuang;
    getline(file, chuang);
    if (chuang.size() % 2 == 1) {
        chuang += "0";
    }
    cout << "得到字符串为 " << chuang << endl;

    vector<int> num;
    for (int i = 0; i < chuang.size(); i += 2) {
        int value = 0;
        value = (int(chuang[i]) * 256) + int(chuang[i + 1]); // Convert 2 characters to int
        num.push_back(value);
    }

    string hexchuang;
    string sum = "0000"; // Initialize sum as "0000"
    for (int i = 0; i < num.size(); i++) {
        int value = num[i];
        sum = add_hex(sum, to_hex(value));
        hexchuang += to_hex(value);
        cout << "转化为16进制后为 " << to_hex(value) << endl;
    }

    cout << "转化为16进制后为 " << hexchuang << endl;
    return sum;
}

int main() {
    string command; // 从命令行输入的命令
    string filename; // 输入的文件名

    cout << "请输入要执行的命令和处理的文件名" << endl;
    cin >> command >> filename;
    //这样运行check_sum D:/infile.txt

    while (true) {
        if (command.compare("check_sum") != 0) {
            cout << "输入命令无效,请重新输入" << endl;
        }
        else {

            cout << "最终的16位校验和: " << check(filename) << endl;
            break;
        }
    }

    return 0;
}

标签:value,16,int,checksum,sum,c++,检验,效验
From: https://www.cnblogs.com/l-xx123/p/18237938

相关文章

  • C++ STL常用容器之map(关联容器)
    文章目录前言一、map的介绍1.1使用map的优点1.2使用map的缺点1.3使用场景二、map常用的操作2.1创建、初始化以及遍历容器2.2查询容器大小2.3访问容器中的元素2.4往容器中添加元素2.5删除容器中的元素2.6清空容器中的元素三、扩展3.1红黑树的概念3.2红黑树的......
  • C++ 中不应抛出异常的函数总结
    在C++中,异常处理是一个重要的特性,它允许程序在遇到错误时能够优雅地恢复。然而,并不是所有的函数都适合抛出异常。以下是一些不应抛出异常的函数类型:析构函数:析构函数负责资源的清理和释放。如果析构函数抛出异常,并且没有被捕获,那么程序可能会终止。这会导致资源泄露或程序......
  • 如何将可选类型从 C++ 传递到 Cython?
    我正在尝试将可选参数从C++传递到Cython文件。我不必将其写入.pxd和.pyx文件中:[C++]std::optional<std::shared_ptr<CPP_MyObject>>cpp_find_value();[.pxd]shared_ptr[CPP_MyObject]cpp_find_value()#fixme[.pyx]defpython_find_value(self)......
  • 【普及组】广度优先搜索BFS——到达型搜索问题_C++算法竞赛
    文章目录1.走迷宫例1.洛谷B3625迷宫寻路例2.洛谷P1825[USACO11OPEN]CornMazeS例3.[ABC348D]MedicinesonGrid(AtCoder)2.生活背景下的常见问题例.P3958[NOIP2017提高组]奶酪3.输出路径例.洛谷P6207[USACO06OCT]CowsonSkatesGEnd提示:本文建议有一定......
  • C++引用(reference)
    在C++中,引用(reference)是一个已存在变量的别名,它允许你为变量提供一个或多个额外的名字。引用在定义时必须初始化,并且一旦初始化后,就不能再引用其他变量。引用和它所引用的变量共享相同的内存地址。以下是C++中引用的基本用法:cpp#include<iostream>intmain(){inta=10;......
  • c++ class 和继承
    c++class和继承  #include<iostream>#include<string> //基类classAnimal{protected:std::stringname;public:Animal(conststd::string&name_param):name(name_param){}virtualvoidspeak()const=0;//纯虚函数,派生类需要实现}......
  • C++标准模板(STL)- 概念库 (C++20) - 指定一个类型派生自另一类型 - (std::derived_from)
    概念库提供基础语言概念的定义,它们能用于进行模板实参的编译时校验,以及基于类型属性的函数派发。这些概念在程序中提供等式推理的基础。标准库中的大多数概念一同加上了语法及语义要求。通常,编译器只能检查语法要求。若在使用点语义要求未得到满足,则程序为病式,不要求诊断。......
  • C++11(2): 通用
    31.继承构造函数structB:A{usingA::A;};32.委派构造函数classA{public: A() :A(1234){}//先调用A(int) A(intn1):A(n1,'C'){}//先调用A(int,char) A(charc1):A(2,c1){}//先调用A(int,char)private: A(intn2,charc2):my_......
  • c++ 引用和指针
      c++引用和指针在C++中,引用和指针是两个非常重要的概念,它们有一些相似之处也有一些不同之处。相似之处:引用和指针都可以指向一个对象。引用一旦被初始化指向一个对象后,就不能再指向其他对象,而指针可以在任何时候指向其他对象。不同之处:引用在......
  • 快速完成VsCode C/C++开发环境配置
    前言本人在配置VsCodeC++开发环境时,查看了很多的博客,内容参差不齐,尤其是关于json文件的配置,绕的人头很晕,最终还是通过阅读官方文档,结合部分博客的指引,完成了环境的配置,在此记录本人的配置过程,希望能帮助到大家。事先声明,本文的内容大量引自VsCode官方的文章:https://code.visual......