Comments (3)
package main
import (
"bytes"
"crypto/sha256"
"fmt"
"hash"
"io"
"log"
"os"
"sort"
"strconv"
)
type byteRange struct {
offset int64
length int64
}
func main() {
f, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
h := CalculateDigestSkippingRanges(f, []byteRange{byteRange{5, 5}, byteRange{15, 5}})
fmt.Printf("%x\n", h.Sum(nil))
fmt.Println("Compare to doing it in one go")
fi, err := f.Stat()
if err != nil {
log.Fatal(err)
}
h = sha256.New()
s := io.NewSectionReader(f, 0, fi.Size())
if _, err := io.Copy(h, s); err != nil {
log.Fatal(err)
}
fmt.Printf("%x\n", h.Sum(nil))
}
func CalculateDigestSkippingRanges(f *os.File, ranges []byteRange) hash.Hash {
fi, err := f.Stat()
if err != nil {
log.Fatal(err)
}
fmt.Printf("The file is %d bytes long\n", fi.Size())
// Sort the ranges by offset, so that we can work on them one after another
sort.Slice(ranges, func(i, j int) bool {
return ranges[i].offset < ranges[j].offset
})
h := sha256.New()
// Add to the hash the checksum for the area between offset 0 and the first byteRange
hashRange(f, h, 0, ranges[0].offset)
// Add to the hash the checksum for each range to be excluded
numberOfRanges := len(ranges)
for i, byterange := range ranges {
fmt.Println("range offset", byterange.offset, "length", byterange.length)
hashDummyRange(h, int(byterange.length))
// Add to the hash the checksum for the area after the excluded range until the end of the file
if i == numberOfRanges-1 {
// This was the last excluded range, so we continue to the end of the file
hashRange(f, h, byterange.offset+byterange.length, fi.Size()-(byterange.offset+byterange.length))
} else {
// Up to the beginning of the next excluded range
hashRange(f, h, byterange.offset+byterange.length, ranges[i+1].offset-(byterange.offset+byterange.length))
}
}
return h
}
func hashRange(f *os.File, h hash.Hash, offset int64, length int64) {
fmt.Println("...continuing with checksum from offset", strconv.FormatInt(offset, 10), "for", strconv.FormatInt(length, 10), "bytes")
s := io.NewSectionReader(f, offset, length)
if _, err := io.Copy(h, s); err != nil {
log.Fatal(err)
}
}
func hashDummyRange(h hash.Hash, length int) {
fmt.Println("Checksum for", strconv.Itoa(length), "bytes as if they were 0x00")
h.Write(bytes.Repeat([]byte{0x00}, length))
}
$ xxd file.txt
00000000: 3132 3334 3500 0000 0000 3132 3334 3500 12345.....12345.
00000010: 0000 0000 3132 3334 3536 3738 3930 3132 ....123456789012
00000020: 3334 3536 3738 3930 0a 34567890.
Results in:
The file is 41 bytes long
...continuing with checksum from offset 0 for 5 bytes
range offset 5 length 5
Checksum for 5 bytes as if they were 0x00
...continuing with checksum from offset 10 for 5 bytes
range offset 15 length 5
Checksum for 5 bytes as if they were 0x00
...continuing with checksum from offset 20 for 21 bytes
8701e9551045bb079246c95e8cb86c56fb74f85ee52bb1605aae6d8a09e384a3
Compare to doing it in one go
8701e9551045bb079246c95e8cb86c56fb74f85ee52bb1605aae6d8a09e384a3
from go-appimage.
Note to self, sha256 digest calculation works now like TheAssassin's implementation (which is somewhat non-standard): e511ed7
from go-appimage.
Done
from go-appimage.
Related Issues (20)
- Properly handle SDL2 HOT 4
- AppStream validator gives wrong results and can't be disabled HOT 19
- 'Invalid desktop file' with exit status 1 on Debian HOT 3
- provide persistent releases HOT 10
- [Question] What to say to app dev when "is not a proper AppImage", "too short" ? HOT 18
- Howto for users is missing. HOT 3
- Appimages won't work with fuse3 unless fusermount is symlinked to fusermount3 HOT 4
- How to launch without FUSERMOUNT_PROG variable? HOT 5
- appimagetool don't bundle `immodules.cache` neither set `GTK_IM_MODULE_FILE` HOT 1
- appimagetool don't configure `loaders.cache` HOT 5
- Crash when application has .svg instead of .png icon HOT 4
- Question/Feature Request: Is the "Applications" directory required? HOT 2
- Stack overflow gathering libs HOT 9
- Fuse error on latest build on Ubuntu 20.04. Build 823 works fine HOT 7
- Crash with QFileDialog HOT 1
- Compatible with `linuxdeployqt` parameters ? HOT 1
- Does not work on Debian 12 HOT 8
- Lacking support for typing characters with diacritics HOT 1
- Trying to use go-appimage to deploy, no internet connection? HOT 4
- UDisks showexec issue on zfs HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from go-appimage.