exFAT校验和的计算 [英] Calculation of exFAT checksum

查看:118
本文介绍了exFAT校验和的计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试使用微控制器将磁盘格式化为exFAT.我的问题是,我需要计算一个校验和,该校验和使用VBR(卷启动区)的扇区1到11中的字节将其存储到扇区12中,但是我的结果不正确.如果校验和不正确,则该磁盘将无法被Windows或任何其他可识别exFAT的操作系统使用,因为校验和已通过验证,如果校验和不正确,则会发生致命错误.

I'm currently trying to format a disk to exFAT using a micro controller. My issue is that I need to calculate a checksum that uses the bytes from sector 1 to 11 of the VBR (Volume Boot Region) to store it into sector 12 but my result is incorrect. When the checksum isn't correct, the disk cannot be used by Windows or any other OS that recognizes exFAT since the checksum is verified and a fatal error occures if it's incorrect.

以下是计算32位校验和的函数:

Here's the function that calculates the 32-bit checksum:

uint32_t BootChecksum(char * data, long bytes){
    uint32_t checksum = 0; 
    for (uint32_t i = 0 ; i < bytes ; i++){
        if (i == 106 || i == 107 || i == 112)
            continue;
        checksum = ((checksum << 31) | (checksum >> 1)) + (uint32_t) data[i];
        if(checksum == 0xF1924082){
            printf("%02X | i = %d", checksum, i);
        }
    }
    return checksum;
}

从我已经能够读取的内容来看,该功能是正确的,因此我的猜测是我使用的数据不正确.我只是简单地提取了所需的11个扇区,因此每个扇区512字节会产生5632字节的数组.

From what I've been able to read, the function is correct so my guess is that the data that I use are incorrect. I'm simply taking the 11 sectors needed so with 512 bytes per sector it results in an array of 5632 bytes.

我使用了类似的函数来计算条目集的校验和(一个16位校验和),结果是正确的,它确实必须是数据,但我不知道我在那里缺少什么!

I've used a similar function to calculate the checksum of the entry set (a 16 bit checksum) and the result is correct, it really has to be the data but I don't understand what I'm missing there!

任何知道exFAT的人都可以帮助我吗?谢谢!

Anyone who knows about exFAT can help me out? Thanks!

推荐答案

我怀疑这是运算符优先级的问题.

I suspect it's a problem of operator precedence.

此页面中,我看到了crc定义,其中 checksum 以此方式修改

In this page I see the crc definition where checksum is modified in this way

checksum = (checksum<<31) | (checksum>> 1) + data[i];

也就是说,如果我没记错的话,它等同于

that is, if I'm not wrong, equivalent to

checksum = (checksum<<31) | ((checksum>> 1) + data[i]);

因为(如果我记得很好),加号运算符( + )的优先级比位或运算符( | )大.

because (if I remember well) the plus operator (+) has a bigger precedence than the bit or operator (|).

相反,您的代码是

checksum = ((checksum << 31) | (checksum >> 1)) + (uint32_t) data[i];

这是完全不同的代码,因为您首先应用按位或,然后再应用加号.

that is a total different code because you first apply the bitwise or and next the plus.

我想可以和

checksum = (checksum << 31) | ((checksum >> 1) + (uint32_t) data[i]);

p.s .:对不起,我的英语不好

p.s.: sorry for my bad English

---编辑2016.06.09 ---

---EDIT 2016.06.09---

另一个问题应该是 data 的签名.

Another problem should be the signedness of data.

您将 data 定义为 char 的指针;ntfs.com将 data 定义为 const unsigned char 的数组.

You define data as a pointer of char; ntfs.com define data as an array of const unsigned char.

指针/数组的区别不是问题; const 部分并不重要(但我建议您也将 data 定义为 const );问题(我想)是如果 char 用负值而不是签名的话,是将 char 转换为 uint32_t 的问题>未签名的字符.

The pointer/array difference isn't a problem; the const part ins't important (but I suggest you to define your data as const too); the problem (I suppose) is the conversion to uint32_t of a char, if char is signed with a negative values, instead of a unsigned char.

一个例子:假设您的 data [i] 的值为-1;使用(uint32_t)data [i] ,如果我还记得的话,首先将 data [i] 转换为 int(-1),然后再转换在 uint32_t(-1)中.这样您就会得到4294967295.

An example: suppose that the value of your data[i] is -1; with (uint32_t) data[i], if I remember well, first data[i] is converted in int(-1) and next in uint32_t(-1). So you get 4294967295.

如果您的 data [i] 是一个 unsigned char ,而不是-1,则 data [i] 的值为255;因此,(uint32_t)数据[i] 首先将255转换为 int(255),即255,紧接着 uint32_t(255),即仍为255.

If your data[i] is an unsigned char, instead of -1 data[i] value is 255; so (uint32_t) data[i] first convert 255 to int(255), that is 255, next to uint32_t(255), that remain 255.

简而言之,我的建议是:改变

Briefly, my suggestion is: change

checksum = (checksum << 31) | ((checksum >> 1) + (uint32_t) data[i]);

checksum = (checksum << 31) | ((checksum >> 1) + (uint32_t) (unsigned char) data[i]);

或者简单地

checksum = (checksum << 31) | ((checksum >> 1) + (unsigned char) data[i]);

这篇关于exFAT校验和的计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆