Transaction
33B4C1365E925E…29282D3CFDC4
Block 25,932 · index 0 · indexed
Summary
- Hash
- 33B4C1365E925EF55D9948E4B07C053A0D36E85FC077CF383D1E29282D3CFDC4
- Block
- 25,932
- Size
- 5604 bytes
- Gas used
- 9,823,226 / 11,787,931
- Fee
- 1000000ugnot
- Memo
- gnopublish
- Status
- success
Messages
Arguments · 9
- #1crc32
- #2README.md
- #3# `gno.land/p/moul/x/daily/crc32/v0` **CRC-32 checksum** — `Checksum`, `ChecksumHex`, `ChecksumWith`, `Verify`, `MakeTable`, `Update`, `Finalize`, `Hex`, `Split`. Treats a message as one enormous binary number and takes the remainder of dividing it by a fixed polynomial. The bit-reflected, table-driven form — the one zip, gzip, PNG and Ethernet actually use. ```go import "gno.land/p/moul/x/daily/crc32/v0" crc32.ChecksumHex("123456789") // "cbf43926" — the standard check value crc32.Checksum("abc") // 0x352441C2 crc32.Verify("abc", 0x352441C2) // true ``` Three polynomials: `IEEE` (zip/gzip/PNG, the default), `Castagnoli` (iSCSI/btrfs, better error detection) and `Koopman`. `MakeTable` builds the 256-entry table once — that is the whole point of the table-driven form, trading 1 KiB for eight bit-shifts per byte. `Update`/`Finalize` take and return the **raw register**, not the finished checksum, so a long message can be fed in chunks. Chaining on final values would be wrong; there is a test asserting chunked equals one-shot. > ⚠️ **A CRC detects accidents, not tampering.** It is linear, so anyone can > craft a different message with the same checksum. Never use it to > authenticate anything. **Live demo:** [`r/moul/x/daily/crc32demo`](https://github.com/moul/gno-contracts/tree/main/r/moul/x/daily/crc32demo/v0) · render it at [`/r/moul/x/daily/crc32demo/v0`](https://gno.land/r/moul/x/daily/crc32demo/v0). <!-- BEGIN GNOCONTRACTS FOOTER (generated by `make readmes`; do not edit below) --> --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. > 🧪 **Highly experimental — potentially vibe-coded.** Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md). <!-- END GNOCONTRACTS FOOTER -->
- #4crc32.gno
- #5// Package crc32 implements the CRC-32 checksum as a pure, reusable package. // // CRC-32 treats a message as one enormous binary number and takes the remainder // of dividing it by a fixed polynomial. The bit-reflected, table-driven form // implemented here is the one everything actually uses — zip, gzip, PNG, and // Ethernet all speak IEEE. // // Three polynomials are provided: // // - IEEE (0xEDB88320) — zip/gzip/PNG. The default. // - Castagnoli (0x82F63B78) — iSCSI/btrfs; better error detection. // - Koopman (0xEB31D82E) // // A CRC is an ACCIDENT detector, not a security primitive: it is linear, so // anyone can craft a different message with the same checksum. Never use it to // authenticate anything. // // A live demo of this package is at // [r/moul/x/daily/crc32demo](/r/moul/x/daily/crc32demo/v0). package crc32 import "strings" // Common reversed polynomials. const ( IEEE = 0xEDB88320 Castagnoli = 0x82F63B78 Koopman = 0xEB31D82E ) // Table is a precomputed byte-wise lookup table for one polynomial. type Table [256]uint32 // MakeTable builds the lookup table for a reversed polynomial. Building it once // and reusing it is the whole point of the table-driven form: it trades 1 KiB // for eight bit-shifts per byte. func MakeTable(poly uint32) *Table { var t Table for i := 0; i < 256; i++ { crc := uint32(i) for j := 0; j < 8; j++ { if crc&1 != 0 { crc = (crc >> 1) ^ poly } else { crc >>= 1 } } t[i] = crc } return &t } var ieeeTable = MakeTable(IEEE) // Update adds the bytes of s to a running checksum. // // Takes and returns the RAW register, not the final value: the caller-visible // checksum is the register XOR 0xFFFFFFFF, so chaining Update calls on final // values would be wrong. Start from 0 and finish with Finalize. func Update(crc uint32, t *Table, s string) uint32 { for i := 0; i < len(s); i++ { crc = t[byte(crc)^s[i]] ^ (crc >> 8) } return crc } // Finalize turns a running register into the checksum. func Finalize(crc uint32) uint32 { return crc ^ 0xFFFFFFFF } // ChecksumWith returns the CRC-32 of s under the given table. func ChecksumWith(s string, t *Table) uint32 { return Finalize(Update(0xFFFFFFFF, t, s)) } // Checksum returns the IEEE CRC-32 of s — the one zip, gzip and PNG use. func Checksum(s string) uint32 { return ChecksumWith(s, ieeeTable) } // Hex renders a checksum as eight lowercase hex digits, zero-padded, which is // how CRCs are conventionally shown. func Hex(crc uint32) string { const digits = "0123456789abcdef" var b [8]byte for i := 7; i >= 0; i-- { b[i] = digits[crc&0xF] crc >>= 4 } return string(b[:]) } // ChecksumHex is Checksum rendered with Hex. func ChecksumHex(s string) string { return Hex(Checksum(s)) } // Verify reports whether s has the expected checksum. func Verify(s string, expected uint32) bool { return Checksum(s) == expected } // Split returns the checksum of each line of s, in order. func Split(s string) []string { out := []string{} for _, line := range strings.Split(s, "\n") { out = append(out, ChecksumHex(line)) } return out }
- #6gnomod.toml
- #7module = "gno.land/p/moul/x/daily/crc32/v0" gno = "0.9"
- #8/gno.MemPackageType
- #9 MPUserProd
Result log
msg:0,success:true,log:,events:[]