# RDB file: CRC64 checksum

**URL:** <https://forum.codecrafters.io/t/rdb-file-crc64-checksum/4191>\
**Category:** Challenges\
**Tags:** challenge:redis\
**Created:** [January 14, 2025, 4:53pm UTC](https://forum.codecrafters.io/t/rdb-file-crc64-checksum/4191 "2025-01-14T16:53:46Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![xuanswe](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/xuanswe/32/4249_2.png) [@xuanswe](https://forum.codecrafters.io/u/xuanswe)\
**Post date:** [January 14, 2025, 4:53pm UTC](https://forum.codecrafters.io/t/rdb-file-crc64-checksum/4191/1 "2025-01-14T16:53:46Z")

</div>

My question is not a requirement of any challenge, but just curiosity.

How the crc64 in rdb file provided in “RDB Persistence” section are computed by testers?

This is the example in hex string (ignore spaces) I got from a CodeCrafter test case in stage “Read a key” #jz6:

```auto
52 45 44 49 53
30 30 31 31

fa
09 72 65 64 69 73 2d 76 65 72
05 37 2e 32 2e 30

fa
0a 72 65 64 69 73 2d 62 69 74 73
c0 40

fe
00
fb
01
00

00
06 62 61 6e 61 6e 61
0a 73 74 72 61 77 62 65 72 72 79

ff
ea d6 77 96 0d d5 e3 65

```

The value “ea d6 77 96 0d d5 e3 65” is 7341946071879767786 (little-endian) or 16921844136252138341 (big-endian).

I tried different poly values:

- ISO: 0xD800000000000000
- ECMA 182: 0xC96C5795D7870F42
- Redis custom poly: 0xad93d23594c935a9 ([redis/src/crc64.c at 7.4 · redis/redis · GitHub](http://github.com/redis/redis/blob/7.4/src/crc64.c#L33))

I tried both cases:

- exclue “ff ea d6 77 96 0d d5 e3 65”
- include “ff ea d6 77 96 0d d5 e3 65”

But cannot result in either crc64 7341946071879767786 (little-endian) or 16921844136252138341 (big-endian) in the given example.

So, could anyone tell me

- What is the poly value to be used by testers?
- Which content in the example above should be included in the crc64 computation?
- Is there anything I am missing in the calculation? For example, in [this tool](https://www.sunshine2k.de/coding/javascript/crc/crc_js.html), I see that there are some more input fields rather than just the poly value.
- It would be nice if you could use an online tool and give me the screenshot of the tool with the input/output.

Thank you a lot!

---

<div class="post-metadata">

**Author:** ![andy1li](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/andy1li/32/10_2.png) [@andy1li](https://forum.codecrafters.io/u/andy1li)\
**Post date:** [January 15, 2025, 4:06am UTC](https://forum.codecrafters.io/t/rdb-file-crc64-checksum/4191/2 "2025-01-15T04:06:05Z")

</div>

Thanks for your questions! I’ll check with the team and get back to you as soon as I can.

---

<div class="post-metadata">

**Author:** ![xuanswe](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/xuanswe/32/4249_2.png) [@xuanswe](https://forum.codecrafters.io/u/xuanswe)\
**Post date:** [January 19, 2025, 3:42pm UTC](https://forum.codecrafters.io/t/rdb-file-crc64-checksum/4191/4 "2025-01-19T15:42:21Z")

</div>

I found a partial answer. Below is explained in Go.

First of all, the poly should be bitwise-reversed of `0xad93d23594c935a9`

```Go
bits.Reverse64(0xad93d23594c935a9) // 0x95ac9329ac4bc9b5

```

Secondly, the Go package `hash/crc64` DO REVERSE the current crc value when computing new crc, then DO REVERSE the new crc again. This logic is fixed in `hash/crc64`.

The tester using `github.com/hdt3213/rdb v1.0.18`. This package DO NOT REVERSE crc value at all.

Below is the code diff from both packages.

```Go
// code from hash/crc64
func update(crc uint64, tab *Table, p []byte) uint64 {
    buildSlicing8TablesOnce()
    crc = ^crc

    // exclude same logic

    return ^crc
}

```

```Go
// code from github.com/hdt3213/rdb
func update(crc uint64, tab *Table, p []byte) uint64 {
    buildSlicing8TablesOnce()

    // exclude same logic

    return crc
}

```

I copied the code from hdt3213/rdb and tried to add the missing logic from hash/crc64. This produces the consistent result between 2 packages.

However, I cannot produce the crc in the example yet even with hdt3213/rdb and the correct poly. I will come back if I find something.

---

<div class="post-metadata">

**Author:** ![xuanswe](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/xuanswe/32/4249_2.png) [@xuanswe](https://forum.codecrafters.io/u/xuanswe)\
**Post date:** [January 19, 2025, 4:31pm UTC](https://forum.codecrafters.io/t/rdb-file-crc64-checksum/4191/5 "2025-01-19T16:31:22Z")

</div>

Coud you please check this code and tell me what’s wrong [Go Playground - The Go Programming Language](https://go.dev/play/p/7m02VeognAB)

---

<div class="post-metadata">

**Author:** ![xuanswe](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/xuanswe/32/4249_2.png) [@xuanswe](https://forum.codecrafters.io/u/xuanswe)\
**Post date:** [January 19, 2025, 4:41pm UTC](https://forum.codecrafters.io/t/rdb-file-crc64-checksum/4191/6 "2025-01-19T16:41:18Z")

</div>

OK. I found the correct computation.  
We need to include the EOF opcode 0xFF.

> **[Go Playground - The Go Programming Language](https://go.dev/play/p/km_Ccn7C7UG)**

```Go
package main

import (
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"strings"

	"github.com/hdt3213/rdb/crc64jones"
	"github.com/rs/zerolog/log"
)

func main() {
	data := []byte("123456789")
	crc := crc64jones.New()
	crc.Write(data)
	crcHex := fmt.Sprintf("%016x", crc.Sum64())
	fmt.Println(crcHex)
	if crcHex != "e9c6d914c4b8d9ca" {
		log.Error().Msg("CRC mismatch")
	}

	data = hexToBytes(
		`52 45 44 49 53 30 30 31 31 fa 09 72 65 64 69 73 2d 76 65 72 05 37 2e 32 2e 30 fa 0a 72 65 64 69 73 2d 62 69 74 73 c0 40 fe 00 fb 01 00 00 06 6f 72 61 6e 67 65 09 62 6c 75 65 62 65 72 72 79 ff`,
		// 35 42 87 36 10 d3 17 f6
	)
	crc = crc64jones.New()
	crc.Write(data)
	fmt.Printf("%016x\n", binary.BigEndian.Uint64(crc.Sum(nil)))

	data = hexToBytes(
		`52 45 44 49 53 30 30 31 31 fa 09 72 65 64 69 73 2d 76 65 72 05 37 2e 32 2e 30 fa 0a 72 65 64 69 73 2d 62 69 74 73 c0 40 fe 00 fb 01 00 00 06 62 61 6e 61 6e 61 0a 73 74 72 61 77 62 65 72 72 79 ff`,
		// ea d6 77 96 0d d5 e3 65
	)
	crc = crc64jones.New()
	crc.Write(data)
	fmt.Printf("%016x\n", binary.BigEndian.Uint64(crc.Sum(nil)))
}

func hexToBytes(h string) []byte {
	h = strings.ReplaceAll(h, " ", "")
	data, _ := hex.DecodeString(h)
	return data
}

```

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/3X/7/0/700657133935c15703e22c7c8870394f6e6dc27d.svg) [@system](https://forum.codecrafters.io/u/system)\
**Post date:** [January 24, 2025, 5:05pm UTC](https://forum.codecrafters.io/t/rdb-file-crc64-checksum/4191/8 "2025-01-24T17:05:52Z")

</div>

Closed on January 24, 2025, 5:05pm UTC

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.
