bitutil.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. /*
  10. Package bitutil contains common function for bit-level operations.
  11. Pack and Unpack functions are used to pack and unpack a list of non-zero numbers
  12. very efficiently.
  13. */
  14. package bitutil
  15. import (
  16. "bytes"
  17. "fmt"
  18. "math"
  19. )
  20. /*
  21. CompareByteArray compares the contents of two byte array slices. Returns true
  22. if both slices are equivalent in terms of size and content. The capacity may
  23. be different.
  24. */
  25. func CompareByteArray(arr1 []byte, arr2 []byte) bool {
  26. if len(arr1) != len(arr2) {
  27. return false
  28. }
  29. for i, v := range arr1 {
  30. if v != arr2[i] {
  31. return false
  32. }
  33. }
  34. return true
  35. }
  36. /*
  37. ByteSizeString takes a numeric byte size and returns it in human readable form.
  38. The useISU parameter determines which units to use. False uses the more common
  39. binary form. The units kibibyte, mebibyte, etc were established by the
  40. International Electrotechnical Commission (IEC) in 1998.
  41. useISU = True -> Decimal (as formally defined in the International System of Units)
  42. Bytes / Metric
  43. 1000^1 kB kilobyte
  44. 1000^2 MB megabyte
  45. 1000^3 GB gigabyte
  46. 1000^4 TB terabyte
  47. 1000^5 PB petabyte
  48. 1000^6 EB exabyte
  49. useISU = False -> Binary (as defined by the International Electrotechnical Commission)
  50. Bytes / Metric
  51. 1024^1 KiB kibibyte
  52. 1024^2 MiB mebibyte
  53. 1024^3 GiB gibibyte
  54. 1024^4 TiB tebibyte
  55. 1024^5 PiB pebibyte
  56. 1024^6 EiB exbibyte
  57. */
  58. func ByteSizeString(size int64, useISU bool) string {
  59. var byteSize, unit float64 = float64(size), 1024
  60. var pre string
  61. if useISU {
  62. unit = 1000
  63. }
  64. if byteSize < unit {
  65. return fmt.Sprintf("%d B", int(byteSize))
  66. }
  67. exp := math.Floor(math.Log(byteSize) / math.Log(unit))
  68. if useISU {
  69. pre = string("kMGTPE"[int(exp-1)])
  70. } else {
  71. pre = fmt.Sprintf("%vi", string("KMGTPE"[int(exp-1)]))
  72. }
  73. res := byteSize / math.Pow(unit, exp)
  74. return fmt.Sprintf("%.1f %sB", res, pre)
  75. }
  76. /*
  77. HexDump produces a more-or-less human readable hex dump from a given byte array
  78. slice.
  79. */
  80. func HexDump(data []byte) string {
  81. buf := new(bytes.Buffer)
  82. line := new(bytes.Buffer)
  83. buf.WriteString("====\n000000 ")
  84. for i, b := range data {
  85. if i != 0 && i%10 == 0 {
  86. buf.WriteString(fmt.Sprintf(" %s\n%06x ", line.String(), i))
  87. line = new(bytes.Buffer)
  88. }
  89. buf.WriteString(fmt.Sprintf("%02X ", b))
  90. line.WriteString(fmt.Sprintf("%c", b))
  91. }
  92. rest := len(data) % 10
  93. if rest != 0 {
  94. for i := rest; i < 10; i++ {
  95. buf.WriteString(" ")
  96. }
  97. }
  98. buf.WriteString(fmt.Sprintf(" %s\n====\n", line.String()))
  99. return buf.String()
  100. }