Skip to content

Instantly share code, notes, and snippets.

@juergenhoetzel
Created December 8, 2018 09:43
Show Gist options
  • Save juergenhoetzel/2d9447cdf5c5b30278adfa7e22ec660e to your computer and use it in GitHub Desktop.
Save juergenhoetzel/2d9447cdf5c5b30278adfa7e22ec660e to your computer and use it in GitHub Desktop.
Decode utf16 (little or big endian) to string
package main
import (
"bytes"
"encoding/binary"
"fmt"
"unicode/utf16"
)
func DecodeUtf16(b []byte, order binary.ByteOrder) (string, error) {
ints := make([]uint16, len(b)/2)
if err := binary.Read(bytes.NewReader(b), order, &ints); err != nil {
return "", err
}
return string(utf16.Decode(ints)), nil
}
func main() {
b := []byte{
0xff, // BOM
0xfe, // BOM
0x3D, // Pile
0xD8, // of
0xA9, // Poo
0xDC, // ---
'T',
0x00,
'E',
0x00,
'S',
0x00,
'T',
0x00,
0x6C,
0x34,
'\n',
0x00,
}
bom := [2]byte{b[0], b[1]}
var s string
var err error
switch bom {
case [2]byte{0xff, 0xfe}:
s, err = DecodeUtf16(b[2:], binary.LittleEndian)
case [2]byte{0xfe, 0xff}:
s, err = DecodeUtf16(b[2:], binary.BigEndian)
default: // just try little endian
s, err = DecodeUtf16(b, binary.LittleEndian)
}
if err != nil {
fmt.Println(err)
} else {
fmt.Println(s)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment