|
package main |
|
|
|
import ( |
|
"bytes" |
|
"compress/gzip" |
|
"crypto/sha1" |
|
"encoding/base64" |
|
"fmt" |
|
"io" |
|
"os" |
|
) |
|
|
|
func getApkPackageChecksum(r io.Reader) (string, error) { |
|
b, err := io.ReadAll(r) |
|
if err != nil { |
|
return "", fmt.Errorf("gzip.NewReader(): %w", err) |
|
} |
|
bio := bytes.NewReader(b) |
|
gzi, err := gzip.NewReader(bio) |
|
if err != nil { |
|
return "", fmt.Errorf("gzip.NewReader(): %w", err) |
|
} |
|
gzi.Multistream(false) |
|
firstPos, err := bio.Seek(0, os.SEEK_CUR) |
|
if err != nil { |
|
return "", fmt.Errorf("bio.Seek() (first): %w", err) |
|
} |
|
if _, err := io.Copy(io.Discard, gzi); err != nil { |
|
return "", err |
|
} |
|
if err = gzi.Reset(bio); err != nil { |
|
return "", fmt.Errorf("gzi.Reset(): %w", err) |
|
} |
|
secondPos, err := bio.Seek(0, os.SEEK_CUR) |
|
if err != nil { |
|
return "", fmt.Errorf("bio.Seek() (second): %w", err) |
|
} |
|
if err := gzi.Close(); err != nil { |
|
return "", fmt.Errorf("gzi.Close(): %w", err) |
|
} |
|
hasher := sha1.New() |
|
if _, err := hasher.Write(b[firstPos-10 : secondPos-10]); err != nil { |
|
return "", fmt.Errorf("hasher.Write(): %w", err) |
|
} |
|
return "Q1" + base64.StdEncoding.EncodeToString(hasher.Sum(nil)), nil |
|
} |
|
|
|
func main() { |
|
args := os.Args[1:] |
|
if len(args) != 1 { |
|
fmt.Println("Usage: go run main.go <package.apk>") |
|
os.Exit(1) |
|
} |
|
file, err := os.Open(args[0]) |
|
if err != nil { |
|
panic(err) |
|
} |
|
defer file.Close() |
|
checksum, err := getApkPackageChecksum(file) |
|
if err != nil { |
|
panic(err) |
|
} |
|
fmt.Println(checksum) |
|
} |