2017-09-05 77 views
0

我正在做一些整數壓縮的工作。
我已經在C++中實現了可變字節編碼算法(請參閱下面的代碼片段)。如何在golang中實現可變字節編碼算法

我不知道如何實現它在golang因爲我不能在內存中轉換int類型之間stringtune 類型memcpy()一樣。

然後,我已經計算出binary.Write()encoding/binary可以做序列化工作,它可以將uint8編碼爲一個字節,unint16編碼爲2個字節,uint32編碼爲4種類型等等。

但如何編碼一個整數,介於2097152和268435456之間,只使用3個字節?

有沒有類似的片段轉換方法?

void encode(int value, char* code_list, int& len) { 

    int bit_value = 0; 
    int bit_num = 0; 

    if (value < 128) { 
    bit_num = 1; 
    } else if (value < 16384) { 
    bit_num = 2; 
    bit_value = 1; 
    } else if (value < 2097152) { 
    bit_num = 3; 
    bit_value = 3; 
    } else { 
    bit_num = 4; 
    bit_value = 7; 
    } 
    value <<= bit_num; 
    value += bit_value; 
    memcpy(code_list + len, (char*) &value, bit_num); 
    len += bit_num; 

} 

回答

3

你的編碼是這樣的,最低顯著1位的第一個字節計數告訴你的編碼值多少字節了。

這是您的代碼的執行,避免依賴於排序(您的C版本),並使用io.Writer而不是memcpy

看到它運行在:https://play.golang.org/p/jr0NypSnlW

package main 

import (
    "fmt" 
    "bytes" 
    "io" 
) 

func encode(w io.Writer, n uint64) error { 
    bytes := 0 
    switch { 
    case n < 128: 
     bytes = 1 
     n = (n << 1) 
    case n < 16834: 
     bytes = 2 
     n = (n << 2) | 1 
    case n < 2097152: 
     bytes = 3 
     n = (n << 3) | 3 
    default: 
     bytes = 4 
     n = (n << 4) | 7 
    } 
    d := [4]byte{ 
     byte(n), byte(n>>8), byte(n>>16), byte(n>>24), 
    } 
    _, err := w.Write(d[:bytes]) 
    return err 
} 

func main() { 
    xs := []uint64{0, 32, 20003, 60006, 300009} 
    var b bytes.Buffer 
    for _, x := range xs { 
     if err := encode(&b, x); err != nil { 
      panic(err) 
     } 
    } 
    fmt.Println(b.Bytes()) 
} 
+0

知道了,謝謝。 – Will