首页 > 其他分享 >Android开发 - “效验和”效验数据在传输或存储过程中是否出错解析

Android开发 - “效验和”效验数据在传输或存储过程中是否出错解析

时间:2024-08-28 21:04:32浏览次数:10  
标签:字节 校验 CRC 异或 出错 效验 byte data Android

校验和的基本原理

  • 校验和的基本原理非常简单,就是把一组数据中的所有字节(或者其他单位)数值相加,然后得到一个总和,这个总和就是所谓的“校验和”。在传输数据时,发送方会把数据校验和一起发送出去;接收方收到数据后,也会计算一次校验和,然后与发送方提供的校验和进行比较。如果两个校验和相同,就认为数据是完整的;如果不同,说明数据传输过程中发生了错误

简单的例子

  • 假设有一个数据包,其中包含了以下 4 个字节的数据:

    10101100
    01101010
    11110000
    00001111
    
  • 如果用一个简单的校验和算法来检测这些数据是否有错误,可以将这 4 个字节的数值相加,得到一个总和。为了方便理解,把这些二进制数转换成十进制数

    • 10101100 = 172

    • 01101010 = 106

    • 11110000 = 240

    • 00001111 = 15

  • 计算校验和的值

    校验和 = 172 + 106 + 240 + 15 = 533
    
    • 这个533就是数据的校验和发送方会把这 533 作为数据包的一部分发送接收方接收方在收到数据包后,会重新计算一次校验和,并与发送方校验和进行比较。如果结果533,则数据没有出错;如果不是 533,则表示数据传输过程中有错误

常见的校验和类型

简单加法校验和

  • 像上面例子一样,将所有数据数值相加,得到一个总和。计算非常简单,但无法检测出所有类型的错误

    public class SimpleChecksum {
    
        /**
         * 计算简单加法校验和
         * 
         * @param data 字节数组
         * @return 校验和(整数)
         */
        public static int calculateChecksum(byte[] data) {
            int checksum = 0; // 初始化校验和为0
    
            for (byte b : data) {
                checksum += b; // 将每个字节的值相加
            }
    
            return checksum & 0xFF; // 返回校验和的低8位
        }
    
        public static void main(String[] args) {
            // 示例数据
            byte[] data = {(byte) 0xAC, (byte) 0x6A, (byte) 0xF0, (byte) 0x0F};
    
            // 计算校验和
            int checksum = calculateChecksum(data);
            System.out.printf("Simple Checksum: 0x%02X%n", checksum); // 输出结果为十六进制格式
        }
    }
    
    • 遍历数据数组,将每个字节数值相加,结果取低8位

异或校验和

  • 使用异或(XOR)运算符计算数据校验和异或校验和比简单加法校验和更能发现某些错误类型

    public class XORChecksum {
    
        /**
         * 计算异或校验和
         * 
         * @param data 字节数组
         * @return 校验和(整数)
         */
        public static int calculateChecksum(byte[] data) {
            int checksum = 0; // 初始化校验和为0
    
            for (byte b : data) {
                checksum ^= b; // 计算每个字节的异或校验和
            }
    
            return checksum;
        }
    
        public static void main(String[] args) {
            // 示例数据
            byte[] data = {(byte) 0xAC, (byte) 0x6A, (byte) 0xF0, (byte) 0x0F};
    
            // 计算校验和
            int checksum = calculateChecksum(data);
            System.out.printf("XOR Checksum: 0x%02X%n", checksum); // 输出结果为十六进制格式
        }
    }
    
    • 遍历数据数组,对每个字节进行异或操作,最终得到一个校验值

CRC-8 校验和

  • 简单加法异或校验和复杂,也更可靠CRC 使用了一种数学算法来产生校验和,能检测出大多数常见错误类型,比如单个错误位多个连续错误位CRC网络通信协议常用的校验方法

    public class CRC8Checksum {
    
        private static final int POLYNOMIAL = 0x07; // CRC-8多项式
    
        /**
         * 计算CRC-8校验码
         * 
         * @param data 字节数组
         * @return CRC-8的值(整数)
         */
        public static int calculateCRC8(byte[] data) {
            int crc = 0; // 初始化CRC为0
    
            for (byte b : data) {
                crc ^= b; // 当前字节与CRC进行异或
    
                for (int i = 0; i < 8; i++) { // 对每一位进行处理
                    if ((crc & 0x80) != 0) { // 如果最高位是1
                        crc = (crc << 1) ^ POLYNOMIAL; // 左移1位并与多项式进行异或
                    } else {
                        crc <<= 1; // 仅左移1位
                    }
                    crc &= 0xFF; // 确保CRC值在8位以内
                }
            }
    
            return crc;
        }
    
        public static void main(String[] args) {
            // 示例数据
            byte[] data = {(byte) 0xAC, (byte) 0x6A, (byte) 0xF0, (byte) 0x0F};
    
            // 计算CRC-8
            int crc = calculateCRC8(data);
            System.out.printf("CRC-8: 0x%02X%n", crc); // 输出结果为十六进制格式
        }
    }
    
    • 遍历数据数组,对每个字节和已有CRC值进行异或,然后根据CRC多项式进行逐位运算,最终得到一个8位的CRC值

校验和的优势和局限性

  • 优势:

    • 简单高效:计算校验和的算法通常非常简单,计算速度快,适合在资源有限的系统中使用

    • 快速错误检测:能够快速检测出数据传输过程中发生的错误

  • 局限性:

    • 有限的错误检测能力:简单的校验和算法,如简单加法异或,可能无法检测出某些类型的错误(例如,数据的顺序发生变化,或两个相互抵消的错误)
    • 不适用于高安全性需求的场合:对于需要高数据完整性安全性应用场景(例如金融交易、敏感数据传输),通常使用更复杂可靠的校验方法,如 CRCHMAC(基于哈希的消息认证码)

总结

  • 校验和是一种用于验证数据完整性检测数据传输或存储过程中错误的简单而有效的工具。通过简单的加法异或更复杂的算法(如 CRC)校验和能帮助确保数据在传输过程中不被篡改或损坏。虽然校验和并不是最可靠的错误检测方法,但由于其计算效率高实现简单它在许多应用场景中仍然非常有用

标签:字节,校验,CRC,异或,出错,效验,byte,data,Android
From: https://www.cnblogs.com/ajunjava/p/18385529

相关文章

  • Android开发 - Runnable 类任务接口定义与后台任务待办解析
    什么是RunnableRunnable接口是用来定义一个任务的接口,这个任务可以在线程中执行。通俗地说,它就像一个“待办事项”,用来描述需要在一个单独的线程中完成的工作。Runnable接口非常简单,只定义了一个方法:run()。当一个类实现了Runnable接口时,它需要提供这个方法的实现,里面写上......
  • 如何在Android上恢复永久删除的照片?
    您是否曾经不小心从Android手机中删除了珍贵的照片,并以为它们已经永远消失了?不要恐慌。我们为您提供了有关如何在Android上恢复永久删除的照片的指南。无论是怀旧之旅还是您需要找回的重要记忆,我们都会引导您完成安全、轻松地取回这些照片的步骤。 第1部分:是否可以恢复......
  • Android经典实战之常见的移动端加密算法和用kotlin进行AES-256加密和解密
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点在移动端开发中,数据加密是确保数据传输和存储安全的重要手段。常见的加密算法包括对称加密算法(如AES)、非对称加密算法(如RSA)、散列算法(如SHA-256),以及消息认证码(如......
  • Android经典实战之使用compose时一般用一个activity还是多个
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点在使用JetpackCompose开发Android应用时,选择使用一个Activity还是多个Activity主要取决于应用的架构和复杂性。以下是一些权衡和指导建议,可以帮助你做出决......
  • Android 启动时判断overlay fs是否挂载
    一、背景Android新版本使用super分区替代原来的system、vendor后,就采用了overlayfs文件系统。这种文件系统在执行adbremount后,修改system、vendor分区内容并不是真正存储在原来的位置,而是单独利用super剩余空间或data分区存了一份新的,原来的文件并没有改变。系统使用时判断......
  • Android面试高阶问题:Android屏幕刷新机制与优化指南
    目录1屏幕刷新基础概念1.1CPU与GPU的作用2.2SurfaceFlinger与图形合成2.3帧、帧率与屏幕刷新率2屏幕撕裂与双缓冲机制2.1屏幕撕裂的原因与影响2.2双缓冲机制的工作原理3优化策略与实践3.1性能分析工具与方法3.2优化案例分析与实施3.2.1案例四:异步加载与......
  • 面试必考问题:Android APP耗电最全解析和优化指南
    目录1AndroidAPP耗电原因分析1.1后台应用持续运行1.2高CPU使用率1.3网络使用不当1.4错误代码实现2Android不同版本的耗电优化功能2.1JobSchedulingAPI与BatteryHistorian2.2JobSchedulingAPI的深入解析2.3BatteryHistorian的实际应用2.4结合JobSch......
  • Android网络请求 |(一) 网络基础概念
    一、前端和后端 前端和后端通过接口交互。前端web端:使用的网页,打开的网站都是前端(使用html、css等语言)显示页面以及做一些简单的校验,比如说非空校验app端:android或者object-C(开发ios上的app)开发的app,后端在页面上操作的业务逻辑、功能如:后端控制购物的时候扣除的余额,......
  • 如何有效学习Android Framework:从系统编译到Framework深入
    Android开发者中,不少人希望从应用开发过渡到系统层次的开发,特别是深入理解和掌握Framework的开发技能,这不仅能为你打开新的职业大门,还能让你更深入地理解Android系统的运行机制。本文将介绍如何从系统编译开始,逐步深入到系统应用和Framework的学习路径。1.掌握系统编译:打好基础......
  • Android开发 - IInterface 接口 Binder 机制跨进程通信 (IPC)解析
    什么是IInterfaceIInterface一个接口,用于跨进程通信(IPC)。有时需要让一个应用程序与另一个应用程序或服务进行通信。这些应用程序可能运行在不同的进程中,使用Binder机制来实现这种通信,而IInterface就是Binder机制的一部分简单来说,IInterface是一个基础接口,它为跨......