Changes between Version 58 and Version 59 of HashSourceCodes


Ignore:
Timestamp:
Dec 15, 2014, 7:32:35 PM (10 years ago)
Author:
os
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • HashSourceCodes

    v58 v59  
    18771877echo "61f7751fc2a72bfb <- should be"
    18781878}}}
     1879
     1880=== GO ===
     1881https://github.com/oz/osdb/blob/6a89d7f831a6a3874260fe4677e546d551cad79d/osdb.go#L42
     1882{{{
     1883    import (
     1884        "bytes"
     1885        "encoding/binary"
     1886        "fmt"
     1887        "os"
     1888    )
     1889
     1890    const (
     1891        ChunkSize = 65536 // 64k
     1892    )
     1893
     1894    // Generate an OSDB hash for an *os.File.
     1895    func HashFile(file *os.File) (hash uint64, err error) {
     1896        fi, err := file.Stat()
     1897        if err != nil {
     1898            return
     1899        }
     1900        if fi.Size() < ChunkSize {
     1901            return 0, fmt.Errorf("File is too small")
     1902        }
     1903
     1904        // Read head and tail blocks.
     1905        buf := make([]byte, ChunkSize*2)
     1906        err = readChunk(file, 0, buf[:ChunkSize])
     1907        if err != nil {
     1908            return
     1909        }
     1910        err = readChunk(file, fi.Size()-ChunkSize, buf[ChunkSize:])
     1911        if err != nil {
     1912            return
     1913        }
     1914
     1915        // Convert to uint64, and sum.
     1916        var nums [(ChunkSize * 2) / 8]uint64
     1917        reader := bytes.NewReader(buf)
     1918        err = binary.Read(reader, binary.LittleEndian, &nums)
     1919        if err != nil {
     1920            return 0, err
     1921        }
     1922        for _, num := range nums {
     1923            hash += num
     1924        }
     1925
     1926        return hash + uint64(fi.Size()), nil
     1927    }
     1928
     1929    // Read a chunk of a file at `offset` so as to fill `buf`.
     1930    func readChunk(file *os.File, offset int64, buf []byte) (err error) {
     1931        n, err := file.ReadAt(buf, offset)
     1932        if err != nil {
     1933            return
     1934        }
     1935        if n != ChunkSize {
     1936            return fmt.Errorf("Invalid read %v", n)
     1937        }
     1938        return
     1939    }
     1940}}}