6124


Golangで[]byteをshift-jisの文字列に変換するにはどうすればいいのでしょうか?  
Pythonだとbytes.decode("shift-jis")とかで一発でできるのですが・・・  
デフォルトがutf-8なので `string([]byte)` としてもshift-
jisにならずutf-8になってしまうと思うのですがどうすればいいのでしょうか?


CC BY-SA 3.0
2015-02-07T13:25:05.250
6120
2017-03-25T03:21:25.167
2015-02-10T02:04:34.550
49
5246
question
go shift-jis
Goで[]byteをshift-jisの文字列に変換する


エンコードの変換には、定番の [`text.encoding`](https://godoc.org/golang.org/x/text/encoding)
パッケージを使用しますが、`code.google.com/p/go.text/encoding` パッケージは **使わないでください** 。 去年末
(Go 1.4 に先駆けて) から推奨されるパッケージ名が変わりました。現在では `golang.org/x/text/encoding`
パッケージが使われます。

_サンプルコード_ :

[code]

    package main
    
    import (
        "fmt"
        "strings"
        "bytes"
        "io"
        "io/ioutil"
        "golang.org/x/text/transform"
    //  "code.google.com/p/go.text/transform" // deprecated
        "golang.org/x/text/encoding/japanese"
    //  "code.google.com/p/go.text/encoding/japanese" // deprecated
    )
    
    func transformEncoding( rawReader io.Reader, trans transform.Transformer) (string, error) {
        ret, err := ioutil.ReadAll(transform.NewReader(rawReader, trans))
        if err == nil {
            return string(ret), nil
        } else {
            return "", err
        }
    }
    
    // Convert a string encoding from ShiftJIS to UTF-8
    func FromShiftJIS(str string) (string, error) {
        return transformEncoding(strings.NewReader(str), japanese.ShiftJIS.NewDecoder())
    }
    
    // Convert a string encoding from UTF-8 to ShiftJIS
    func ToShiftJIS(str string) (string, error) {
        return transformEncoding(strings.NewReader(str), japanese.ShiftJIS.NewEncoder())
    }
    
    // Convert an array of bytes (a valid ShiftJIS string) to a UTF-8 string
    func BytesFromShiftJIS(b []byte) (string, error) {
        return transformEncoding(bytes.NewReader(b), japanese.ShiftJIS.NewDecoder())
    }
    
    // Convert an array of bytes (a valid UTF-8 string) to a ShiftJIS string
    func BytesToShiftJIS(b []byte) (string, error) {
        return transformEncoding(bytes.NewReader(b), japanese.ShiftJIS.NewEncoder())
    }
    
    func main() {
        strRaw := "\x8c\x8e\x93\xfa\x82\xcd\x95\x53\x91\xe3\x82\xcc\x89\xdf\x8b\x71" +
                "\x82\xc9\x82\xb5\x82\xc4\x81\x41\x8d\x73\x82\xa9\x82\xd3\x94\x4e" +
                "\x82\xe0\x96\x94\x97\xb7\x90\x6c\x96\xe7\x81\x42"
    
        strUTF := "月日は百代の過客にして、行かふ年も又旅人也。"
    
        // string (ShiftJIS) -> []byte (ShiftJIS)
        bytesRaw := []byte(strRaw)
    
        // string (UTF-8) -> []byte (UTF-8)
        bytesUTF := []byte(strUTF)
    
        // string (ShiftJIS) -> string (UTF-8)
        {
            result, err := FromShiftJIS(strRaw)
            if err != nil {
                panic(err)
            }
            fmt.Println(result)
        }
    
        // []byte (ShiftJIS) -> string (UTF-8)
        {
            result, err := BytesFromShiftJIS(bytesRaw)
            if err != nil {
                panic(err)
            }
            fmt.Println(result)
        }
    
        // []byte (UTF-8) -> string (ShiftJIS)
        {
            result, err := BytesToShiftJIS(bytesUTF)
            if err != nil {
                panic(err)
            }
            fmt.Printf("ByteToShiftJIS: %t", result == strRaw)
        }
    }
    
[/code]

_Output_ :

[code]

    月日は百代の過客にして、行かふ年も又旅人也。
    月日は百代の過客にして、行かふ年も又旅人也。
    ByteToShiftJIS: true
    
[/code]

参考:

  * GoDoc: [`golang.org/x/text/encoding`](https://godoc.org/golang.org/x/text/encoding)
  * GoDoc: [`golang.org/x/text/transform/Transformer`](https://godoc.org/golang.org/x/text/transform#Transformer)
  * golang-nuts: [New import paths for Go sub-respositories](https://groups.google.com/forum/#!topic/golang-nuts/eD8dh3T9yyA)


CC BY-SA 3.0
2015-02-07T15:37:39.930
6124
2015-02-07T16:32:23.463
2015-02-07T16:32:23.463
4978
4978
6120
answer


`text/transform`の[transform.String](https://godoc.org/golang.org/x/text/transform#String)
を使って変換することもできます。

2年前に解決済みの質問ではありますが、`transform.String`の使用例が検索であまり引っかからなかったので、参考までにまとめておきます。

サンプルコード:

[code]

    package main
    
    import (
        "golang.org/x/text/encoding/japanese"
        "golang.org/x/text/transform"
        "fmt"
    )
    
    func GetSjis(target string) string {
        //utf-8->sjis
        text, count, err := transform.String(japanese.ShiftJIS.NewEncoder(), target)
        if err != nil {
            panic(err)
        }
        fmt.Printf("バイト数: %v\n", count)
        return text
    }
    
    func main()  {
        s := "あ" //utf-8
        fmt.Printf("%v: %x\n", s, s)
        s = GetSjis(s) //sjisに変換
        fmt.Printf("%x\n", s)
        bytes := []byte{0x82, 0xA0}
        //sjis->utf-8変換
        s, _, _ = transform.String(japanese.ShiftJIS.NewDecoder(), string(bytes)) //string(bytes)の代わりにsを用いても結果は同じ
        fmt.Printf("%v: %x\n", s, s)
    }
    
[/code]

Output:

[code]

    あ: e38182
    バイト数: 3
    82a0
    あ: e38182
    
[/code]


CC BY-SA 3.0
2017-03-25T03:21:25.167
33517
2017-03-25T03:21:25.167
9820
6120
answer