main.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package main
  2. import (
  3. "encoding/binary"
  4. "encoding/hex"
  5. "fmt"
  6. "hash/crc32"
  7. "io"
  8. "io/ioutil"
  9. "os"
  10. "path/filepath"
  11. "github.com/akamensky/argparse"
  12. )
  13. func swab16(x uint16) uint16 {
  14. return (x&0x00ff)<<8 | (x&0xff00)>>8
  15. }
  16. func swab32(x uint32) uint32 {
  17. return (x&0x000000ff)<<24 | (x&0x0000ff00)<<8 | (x&0x00ff0000)>>8 | (x&0xff000000)>>24
  18. }
  19. func sumArr(arr []uint8) uint32 {
  20. sum := uint32(0)
  21. for _, val := range arr {
  22. sum += uint32(val)
  23. }
  24. return sum
  25. }
  26. func calChecknum(_type string, datas []byte) uint32 {
  27. if _type == "sum32" {
  28. return sumArr(datas)
  29. } else if _type == "crc32" {
  30. return crc32.ChecksumIEEE(datas)
  31. } else {
  32. print("unKown type: " + _type)
  33. return 0
  34. }
  35. }
  36. func getFileSize(filename string) (int64, error) {
  37. fileinfo, err := os.Stat(filename)
  38. if err != nil {
  39. return 0, err
  40. }
  41. size := fileinfo.Size()
  42. return size, nil
  43. }
  44. func ReadBinFile(_name string, _type string, _en string, _block int, _addcheck int) {
  45. FileName := filepath.Base(_name)
  46. // FileType := filepath.Ext(_name)
  47. InputFilePath := _name
  48. OutputFilePath := FileName + "." + _type
  49. inputFile, err := os.Open(InputFilePath)
  50. if err != nil {
  51. panic(err)
  52. }
  53. defer inputFile.Close()
  54. outputFile, err := os.OpenFile(OutputFilePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
  55. if err != nil {
  56. panic(err)
  57. }
  58. defer outputFile.Close()
  59. if _block > 0 {
  60. buffer := make([]byte, _block)
  61. for {
  62. n, err := inputFile.Read(buffer)
  63. if n > 0 {
  64. // 计算分片的校验和
  65. check := calChecknum(_type, buffer[:n])
  66. // 写入分片内容+分片校验和
  67. if _en == "big" {
  68. binary.Write(outputFile, binary.BigEndian, buffer[:n])
  69. binary.Write(outputFile, binary.BigEndian, check)
  70. } else {
  71. binary.Write(outputFile, binary.LittleEndian, buffer[:n])
  72. binary.Write(outputFile, binary.LittleEndian, check)
  73. }
  74. }
  75. if err != nil {
  76. if err == io.EOF {
  77. break // 文件读取完毕
  78. }
  79. panic(err)
  80. }
  81. }
  82. } else {
  83. data, err := ioutil.ReadAll(inputFile)
  84. if err != nil {
  85. panic(err)
  86. }
  87. // 写入全部内容
  88. if _en == "big" {
  89. binary.Write(outputFile, binary.BigEndian, data)
  90. } else {
  91. binary.Write(outputFile, binary.LittleEndian, data)
  92. }
  93. }
  94. // 读取文件内容到字节切片
  95. inputFile, err = os.Open(InputFilePath)
  96. if err != nil {
  97. panic(err)
  98. }
  99. defer inputFile.Close()
  100. data, err := ioutil.ReadAll(inputFile)
  101. if err != nil {
  102. panic(err)
  103. }
  104. check := calChecknum(_type, data[:])
  105. if _addcheck == 1 {
  106. // 追加校验码
  107. if _en == "big" {
  108. binary.Write(outputFile, binary.BigEndian, check)
  109. } else {
  110. binary.Write(outputFile, binary.LittleEndian, check)
  111. }
  112. }
  113. // 大小端转换
  114. var networkBytes [4]byte
  115. if _en == "big" {
  116. binary.BigEndian.PutUint32(networkBytes[:], check)
  117. } else {
  118. binary.LittleEndian.PutUint32(networkBytes[:], check)
  119. }
  120. check_hex := hex.EncodeToString(networkBytes[:])
  121. // 打印输出内容
  122. size, err := getFileSize(InputFilePath)
  123. fmt.Println(InputFilePath, fmt.Sprintf("%d", size), _type, check_hex)
  124. // 关闭文件
  125. err = outputFile.Close()
  126. if err != nil {
  127. fmt.Println(err)
  128. }
  129. // 重命名文件
  130. out_name1 := FileName + "." + _type + "[" + check_hex + "]"
  131. err = os.Rename(OutputFilePath, out_name1)
  132. if err != nil {
  133. fmt.Println("重命名文件出错:", err)
  134. return
  135. }
  136. }
  137. func main() {
  138. parser := argparse.NewParser("goChecknum", "这是一个用于固件校验码工具, 制作升级文件")
  139. _name := parser.String("n", "name", &argparse.Options{Required: true, Help: "bin文件名, 譬如 test.bin", Default: "test.bin"})
  140. _type := parser.String("t", "type", &argparse.Options{Required: false, Help: "校验方式: sum32,crc32", Default: "sum32"})
  141. _en := parser.String("e", "en", &argparse.Options{Required: false, Help: "校验码大小端: little,big", Default: "little"})
  142. _section := parser.Int("s", "section", &argparse.Options{Required: false, Help: "分块大小: 0,1024,2048", Default: 0})
  143. _addcheck := parser.Int("a", "addcheck", &argparse.Options{Required: false, Help: "文件结尾追加校验码", Default: 1})
  144. err := parser.Parse(os.Args)
  145. if err != nil {
  146. fmt.Print(parser.Usage(err)) // 帮助 -h or --help
  147. return
  148. }
  149. ReadBinFile(*_name, *_type, *_en, *_section, *_addcheck)
  150. }