delta_encoding_with_elias_coding.sf 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #!/usr/bin/ruby
  2. # Author: Trizen
  3. # Date: 13 June 2023
  4. # https://github.com/trizen
  5. # Implementation of the Delta encoding scheme, optimized for large deltas, using Elias coding.
  6. # Reference:
  7. # Data Compression (Summer 2023) - Lecture 6 - Delta Compression and Prediction
  8. # https://youtube.com/watch?v=-3H_eDbWNEU
  9. func delta_encode (bytes) {
  10. var deltas = ([0] + bytes -> diffs)
  11. var bitstring = FileHandle.new_buf(:raw)
  12. for d in (deltas) {
  13. if (d == 0) {
  14. bitstring << '0'
  15. }
  16. else {
  17. var t = d.abs.as_bin
  18. bitstring << ('1' + ((d < 0) ? '0' : '1') + '1'*(t.len-1) + '0' + t.substr(1))
  19. }
  20. }
  21. return bitstring.parent
  22. }
  23. func delta_decode (bitstring) {
  24. var bits = bitstring.chars
  25. var deltas = []
  26. while (bits) {
  27. var bit = bits.shift
  28. if (bit == '0') {
  29. deltas << 0
  30. }
  31. else {
  32. var bit = bits.shift
  33. var n = (^Inf -> first { bits.shift != '1' })
  34. var d = Num('1' + n.of { bits.shift }.join, 2)
  35. deltas << (bit == '1' ? d : -d)
  36. }
  37. }
  38. deltas.acc
  39. }
  40. var str = "TOBEORNOTTOBEORTOBEORNOT"
  41. var enc = delta_encode(str.bytes)
  42. var dec = delta_decode(enc)
  43. say "Encoded: #{enc}"
  44. say "Decoded: #{dec.pack('C*')}"
  45. assert_eq(dec.pack('C*'), str)
  46. do {
  47. var str = File(__FILE__).read(:raw)
  48. var encoded = delta_encode(str.bytes)
  49. var decoded = delta_decode(encoded)
  50. assert_eq(str, decoded.pack('C*'))
  51. }
  52. __END__
  53. Encoded: 1111111100101001011001101110101111011111100101110110110001101111001010110011011101011110111111001011101111001011001101110101111011111100101110110110001101111001
  54. Decoded: TOBEORNOTTOBEORTOBEORNOT