繁体   English   中英

将java currentTimeMillis转换为字节的clojure向量

[英]Converting java currentTimeMillis to a clojure vector of bytes

我有一个函数试图将从JVM上可用的currentTimeMillis方法获得的时间(以毫秒为单位)转换为带符号字节的向量。 它在大多数情况下看起来很好,除了一个小问题 - 在达到前8位的最大字节值后,并不总是正确地增加第n个字节位置。 这是一个示例字节序列:

[0 0 1 69 74 87 123 56]
[0 0 1 69 74 87 123 56]
[0 0 1 69 74 87 123 56]
[0 0 1 69 74 87 123 56]
[0 0 1 69 74 87 123 57]
[0 0 1 69 74 87 123 57]
[0 0 1 69 74 87 123 57]
[0 0 1 69 74 87 123 57]
[0 0 1 69 74 87 123 57]
[0 0 1 69 74 87 123 57]
[0 0 1 69 74 87 1 64]
[0 0 1 69 74 87 1 64]
[0 0 1 69 74 87 1 64]
[0 0 1 69 74 87 1 64]
[0 0 1 69 74 87 1 65]
[0 0 1 69 74 87 1 65]
[0 0 1 69 74 87 1 65]
[0 0 1 69 74 87 1 65]
[0 0 1 69 74 87 1 65]
[0 0 1 69 74 87 1 66]
[0 0 1 69 74 87 1 66]

哎呀。 正如您所看到的,右边的第六个字节没有增加到88.这似乎并不是一直发生 - 有时它会正确地增加字节。 这将是一个问题,因为我将此值发送到服务器,该服务器期望时间间隔为必须不断递增的字节值序列。

这是我用来生成这个的代码:

(def max-signed-bytes 128)

(defn byte-at
  "Shifts x by a given number of bits"
  [x offset]
  (mod (bit-shift-right x offset) max-signed-bytes))

(defn Long->bytes
  "Convert a 64-bit integer into a byte vector"
  [^Long x]
  (conj []
        (byte-at x 56)
        (byte-at x 48)
        (byte-at x 40)
        (byte-at x 32)
        (byte-at x 24)
        (byte-at x 16)
        (byte-at x 8)
        (mod x max-signed-bytes)))

(defn time->bytes
  "Returns the current time in milliseconds as a byte vector"
  []
  (Long->bytes (System/currentTimeMillis)))

我尝试使用256对无符号字节值进行修改,但它似乎不会遇到此问题。 但是,我需要一个带符号的字节值才能将内容填充到字节数组中,因为我最终需要使用DataOutputStreamwrite方法编写一个字节数组。

从long获取字节数组的最简单方法可能就是

(defn num->bytes [n] (.toByteArray (biginteger n)))

但是,由于您的编辑指定您正在使用DataOutputStream ,因此只需直接使用writeLong方法

so.core=>(def buffer (java.io.ByteArrayOutputStream.))
#'so.core/buffer
so.core=> (def data-stream (java.io.DataOutputStream. buffer))
#'so.core/data-stream
so.core=> (.writeLong data-stream 257)
nil
so.core=> (.toByteArray buffer)
#<byte[] [B@6ea4b78b>
so.core=> (vec *1)
[0 0 0 0 0 0 1 1]

代码问题与编辑中诊断出的一样。 您需要模数超过可能的字节值数256,而不是最大有符号值128.否则,您将两个字节值映射到相同的数字(= (mod 127 128) (mod -1 128)) ;=> true 转换为字节将被签名(.byteValue (mod 255 256)) ;=> -1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM