Aucune description

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "os"
  6. )
  7. func main() {
  8. var serial, option, value int
  9. var valueStr string
  10. var listOptions bool
  11. flag.BoolVar(&listOptions, "l", false, "list options and exit")
  12. flag.IntVar(&serial, "s", 0, "serial number of receiver")
  13. flag.IntVar(&option, "o", 0, "option number (use -l to list)")
  14. flag.StringVar(&valueStr, "v", "", "option value in hex (typically 00 = enable, FF = disable)")
  15. flag.Parse()
  16. if listOptions {
  17. for i, name := range optionNames {
  18. if name == "" {
  19. continue
  20. }
  21. fmt.Printf("Option %2d = %s\n", i, name)
  22. }
  23. os.Exit(0)
  24. }
  25. if serial == 0 || option == 0 || valueStr == "" {
  26. flag.PrintDefaults()
  27. os.Exit(1)
  28. }
  29. if option < 0 || option > 59 {
  30. fmt.Printf("Option number %d is out of range (allowed: 0-59)\n", option)
  31. os.Exit(1)
  32. }
  33. n, err := fmt.Sscanf(valueStr, "%2x", &value)
  34. if n == 0 || err != nil {
  35. fmt.Println("Unable to parse option value.")
  36. os.Exit(1)
  37. }
  38. e := encrypt(serial, option, value)
  39. fmt.Printf("Receiver Serial Number: %d\n", serial)
  40. if option < len(optionNames) {
  41. fmt.Printf("Option Number: %d (%s)\n", option, optionNames[option])
  42. } else {
  43. fmt.Printf("Option Number: %d (out of range)\n", option)
  44. }
  45. fmt.Printf("Option Value: %02X\n", value)
  46. fmt.Printf("Code: %s\n", e)
  47. return
  48. }
  49. func encrypt(serialNumber, feature, value int) string {
  50. passwordStr := fmt.Sprintf("%05d%02d%02X", serialNumber, feature, value)
  51. password := []byte(passwordStr)
  52. fromASCII(password)
  53. sn := byte(serialNumber) & 0xF
  54. secret := []byte{7, 7, 5, 5, 9, 8, 1, 4, 2}
  55. encrypted := make([]byte, 10)
  56. for x := 0; x < 9; x++ {
  57. encrypted[8-x] = sn ^ secret[8-x] ^ reverseBits(password[x])
  58. }
  59. encrypted[9] = calculateCheck(encrypted)
  60. toASCII(encrypted)
  61. return string(encrypted)
  62. }
  63. func decrypt(serialNumber int, passwordStr string) (int, int, int, error) {
  64. if len(passwordStr) != 10 {
  65. return 0, 0, 0, fmt.Errorf("password must be 10 characters long")
  66. }
  67. password := []byte(passwordStr)
  68. fromASCII(password)
  69. sum := calculateCheck(password)
  70. if password[9] != sum {
  71. return 0, 0, 0, fmt.Errorf("bad checksum")
  72. }
  73. sn := byte(serialNumber) & 0xF
  74. secret := []byte{7, 7, 5, 5, 9, 8, 1, 4, 2}
  75. decrypted := make([]byte, 9)
  76. for x := 0; x < 9; x++ {
  77. decrypted[8-x] = reverseBits(sn ^ secret[x] ^ password[x])
  78. }
  79. toASCII(decrypted)
  80. var serial, option, value int
  81. _, err := fmt.Sscanf(string(decrypted), "%5d%2d%2X", &serial, &option, &value)
  82. if err != nil {
  83. return 0, 0, 0, err
  84. }
  85. return serial, option, value, nil
  86. }
  87. func calculateCheck(password []byte) byte {
  88. sum := 0
  89. for i := 8; i >= 0; i-- {
  90. for j := 3; j >= 0; j-- {
  91. sum += int(password[i]) >> j & 1
  92. }
  93. }
  94. return byte(sum & 0xF)
  95. }
  96. func reverseBits(in byte) byte {
  97. var out byte
  98. for i := 0; i < 4; i++ {
  99. if in&(1<<i) != 0 {
  100. out |= 1 << (3 - i)
  101. }
  102. }
  103. return out
  104. }
  105. func fromASCII(s []byte) {
  106. for i, b := range s {
  107. if b > '9' {
  108. s[i] -= '7'
  109. } else {
  110. s[i] -= '0'
  111. }
  112. }
  113. }
  114. func toASCII(s []byte) {
  115. for i, b := range s {
  116. if b > 9 {
  117. s[i] += '7'
  118. } else {
  119. s[i] += '0'
  120. }
  121. }
  122. }
  123. var optionNames = []string{
  124. "POWER UP PORT SETTINGS",
  125. "POWER UP OUTPUT MSGS",
  126. "LOCATOR",
  127. "POWER UP NV ERASE",
  128. "RTCM ASCII",
  129. "CYCLE PRINT",
  130. "POSITION STATISTICS",
  131. "TAILBOUY",
  132. "PATHFINDER",
  133. "LANDSEIS",
  134. "RTCM NETWORK INPUT",
  135. "CARRIER PHASE",
  136. "HALF CYCLE L2",
  137. "MAXWELL L1 ONLY",
  138. "REMOTE DOWNLOAD",
  139. "DEMO EQUIPMENT ONLY",
  140. "",
  141. "RT SURVEY DATA",
  142. "LOCAL DATUMS",
  143. "RSIM INTERFACE",
  144. "DUAL FREQ / MULTI-BIT",
  145. "RS-232 PORTS",
  146. "MULTIPLE DATUMS",
  147. "EXTERNAL TIMEBASE",
  148. "EVENT MARKER",
  149. "1 PPS",
  150. "",
  151. "FIRMWARE UPDATE",
  152. "RTCM INPUTS",
  153. "RTCM OUTPUTS",
  154. "SYNC INTERVAL",
  155. "NMEA-0183",
  156. "SV SWAPPING",
  157. "KEYBOARD TYPE",
  158. "NAVIGATION",
  159. "LctrCrPh",
  160. "KINEMATIC",
  161. "CONFIGURED",
  162. "DATA LOGGING SIZE",
  163. "SURVEY TYPE",
  164. "RTK OTF CAPABILITIES",
  165. "IONO-FREE POSITIONING",
  166. "",
  167. "I/O DRIVERS",
  168. "",
  169. "CMR TYPE2 RATE",
  170. "RTK SPECIALS",
  171. "",
  172. "",
  173. "",
  174. "",
  175. "",
  176. "",
  177. "",
  178. "",
  179. "",
  180. "",
  181. "",
  182. "",
  183. "",
  184. }