fork download
  1. uncompress=->bytes,verbose=false{
  2. #p bytes
  3. rbytes=[]
  4. i=j=0
  5. getb=->{
  6. b=bytes[i] or raise "#{i},#{j}"
  7. i+=1
  8. b
  9. }
  10. setb=->b{
  11. rbytes[j]=b
  12. j+=1
  13. }
  14. copy=->a,off{
  15. (a+1).times{
  16. rbytes[j]=rbytes[j-off]
  17. j+=1
  18. }
  19. }
  20. buf=0
  21. sbits=0
  22. fill=->{
  23. ibak=i
  24. bl=getb[]
  25. bh=getb[]
  26. w=(bh<<8)|bl
  27. buf|=w<<(16-sbits)
  28. sbits+=16
  29. warn "fill @#{ibak}" if verbose
  30. }
  31. getbw=->{
  32. buf>>16
  33. }
  34. discard=->d{
  35. return if d==0
  36. buf=(buf<<d)&0xffffffff
  37. sbits-=d
  38. if sbits<16
  39. fill[]
  40. end
  41. }
  42. judge1=->{
  43. w=getbw[]
  44. #p "j1: %04x" % w
  45. case w
  46. when 0...0x200
  47. [(w>>2)|0x80, 13]
  48. when 0x200...0x400
  49. [w>>3, 12]
  50. when 0x400...0x800
  51. [w>>5, 10]
  52. when 0x800...0x1000
  53. [w>>7, 8]
  54. when 0x1000...0x2000
  55. [w>>9, 6]
  56. when 0x2000...0x4000
  57. [w>>11, 4]
  58. when 0x4000...0x8000
  59. [w>>13, 2]
  60. else
  61. [1, 0]
  62. end
  63. }
  64. judge2=->{
  65. w=getbw[] & 0x7fff
  66. #p "j2: %04x" % w
  67. w &= 0x7fff
  68. case w
  69. when 0...0x800
  70. [w>>9, 7]
  71. when 0x800...0xc00
  72. [(w>>8)-4, 8]
  73. when 0xc00...0x1800
  74. [(w>>7)-0x10, 9]
  75. when 0x1800...0x3000
  76. [(w>>6)-0x40, 10]
  77. else
  78. sw=8-(w>>12)
  79. [(w&0xfff|0x1000)>>sw, 16-sw]
  80. end
  81. }
  82. fill[]
  83. begin
  84. loop{
  85. warn "getf @#{i}" if verbose
  86. cb=getb[]
  87. warn "flag byte: #{'%08b'%cb}" if verbose
  88. 7.downto(0){|k|
  89. if cb[k]>0
  90. warn "copyraw @#{i} -> @#{j}" if verbose
  91. setb[getb[]]
  92. else
  93. p1,d1=judge1[]
  94. if p1==0xff
  95. warn "detect end mark (p1=0xff)"
  96. break
  97. end
  98. discard[d1]
  99. p2,d2=judge2[]
  100. discard[d2]
  101. if verbose
  102. warn "repeat @#{j} from -#{p2} by #{p1+1}, consume #{d1+d2}"
  103. bufs=("%032b"%buf)[0...sbits]
  104. warn "pooled #{bufs} ( #{sbits} bits )"
  105. end
  106. copy[p1,p2+1]
  107. end
  108. } or break
  109. }
  110. rescue => e
  111. warn " * error #{e} in uncompression *"
  112. end
  113. rbytes
  114. }
  115. cbytes = $<.flat_map{|line| line.scan(/\w\w/).map{|t| t.to_i(16) } }
  116. rbytes=uncompress[cbytes,true]
  117.  
  118. 0.step{|off|
  119. bytes=[]
  120. dobreak=false
  121. 16.times{|i|
  122. b=rbytes[off*16+i] or break
  123. bytes[i]=b
  124. } or dobreak=true
  125. break if bytes.size==0
  126. bstrs=[" "]*16
  127. bytes.each_with_index{|b,i| bstrs[i]="%02x" % b}
  128. puts (" %02x0: %s" % [off, bstrs.each_slice(2).map{|(s1,s2)| s1+s2 }*" "])
  129. break if dobreak
  130. }
Success #stdin #stdout #stderr 0.01s 8032KB
stdin
2040 a000 b018 ff00 46e0 0f05 60
stdout
    000: 0000 0000 ffff ffff 0000 0000 0000 0000
    010: 0000 0000 0000 0000 0000 0000 0000 0000
    020: 0000 0000 0000 0000 0000 0000 0000 0000
stderr
fill @0
getf @2
flag byte: 10100000
copyraw @3 -> @0
fill @4
repeat @1 from -0 by 3, consume 9
pooled 01000000001100010110000 ( 23 bits )
copyraw @6 -> @4
fill @7
repeat @5 from -0 by 3, consume 9
pooled 011000101100000100011000000000 ( 30 bits )
repeat @8 from -7 by 4, consume 10
pooled 00000100011000000000 ( 20 bits )
fill @9
repeat @12 from -0 by 36, consume 17
pooled 0000000111111100000 ( 19 bits )
detect end mark (p1=0xff)