sub_file_hash.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package sub_file_hash
  2. import (
  3. "crypto/md5"
  4. "crypto/sha1"
  5. "fmt"
  6. "github.com/allanpk716/ChineseSubFinder/internal/types/common"
  7. "math"
  8. "os"
  9. )
  10. func Calculate(filePath string) (string, error) {
  11. h := sha1.New()
  12. fp, err := os.Open(filePath)
  13. if err != nil {
  14. return "", err
  15. }
  16. defer func() {
  17. _ = fp.Close()
  18. }()
  19. stat, err := fp.Stat()
  20. if err != nil {
  21. return "", err
  22. }
  23. size := float64(stat.Size())
  24. if size < 0xF000 {
  25. return "", common.VideoFileIsTooSmall
  26. }
  27. samplePositions := [samplingPoints]int64{
  28. 4 * 1024,
  29. int64(math.Floor(size / 4)),
  30. int64(math.Floor(size / 4 * 2)),
  31. int64(math.Floor(size / 4 * 3)),
  32. int64(size - 8*1024)}
  33. fullBlock := make([]byte, samplingPoints*onePointLen)
  34. index := 0
  35. for _, position := range samplePositions {
  36. //f, err := os.Create(filepath.Join("c:\\Tmp", fmt.Sprintf("%d", position)+".videoPart"))
  37. //if err != nil {
  38. // return "", err
  39. //}
  40. oneBlock := make([]byte, onePointLen)
  41. _, err = fp.ReadAt(oneBlock, position)
  42. if err != nil {
  43. //_ = f.Close()
  44. return "", err
  45. }
  46. for _, b := range oneBlock {
  47. fullBlock[index] = b
  48. index++
  49. }
  50. //_, err = f.Write(oneBlock)
  51. //if err != nil {
  52. // return "", err
  53. //}
  54. //_ = f.Close()
  55. }
  56. h.Write(fullBlock)
  57. hashBytes := h.Sum(nil)
  58. return fmt.Sprintf("%x", md5.Sum(hashBytes)), nil
  59. }
  60. const (
  61. samplingPoints = 5
  62. onePointLen = 4 * 1024
  63. )
  64. const checkHash = "f08d48a3e2cd6a02f9fd8ac92743dd3e"