将字符串编码为其ASCII表示形式,字符串长度不同。

huangapple go评论86阅读模式
英文:

Encoding a string to its ASCII representation on varying length of strings

问题

我想使用Go语言的ASCII编码对字符串进行编码,就像下面的C#函数一样:

public static byte[] StrToByteArray(string str)
{
    System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
    return encoding.GetBytes(str);
}

我知道如何使用下面的函数来实现:

import (
    "encoding/ascii85"
    "fmt"
)

func main() {
    dst := make([]byte, 25, 25)
    dst2 := make([]byte, 25, 25)
    ascii85.Encode(dst, []byte("Hello, playground"))
    fmt.Println(dst) 
    ascii85.Decode(dst2, dst, false)
    fmt.Println(string(dst2))
}

目前它的长度是硬编码为25。我该如何根据字符串的大小来调整长度呢?

英文:

I want to encode a string in Go using ASCII encoding like my C# function below:

public static byte[] StrToByteArray(string str)
        {

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            return encoding.GetBytes(str);
        }

I know how to do it using the below function:

import (
        "encoding/ascii85"
	"fmt"
)
func main() {
        dst := make([]byte, 25, 25)
        dst2 := make([]byte, 25, 25)
        ascii85.Encode(dst, []byte("Hello, playground"))
        fmt.Println(dst) 
        ascii85.Decode(dst2, dst, false)
        fmt.Println(string(dst2))
}

Currently it is hard coded to a length of 25. How could I adjust the length based on the size of the string?

答案1

得分: 5

ascii85.MaxEncodedLen() 返回给定输入字节数的最大输出字节数。您可以使用这个上限估计值。

实际使用/写入的字节数由 ascii85.Encode() 返回。如果您将更大的切片传递给 Encode(),您必须使用它来切割目标切片,超出此范围的字节是“垃圾”。

ascii85.Decode() 也是如此:它返回写入的字节数,如果您传递了更大的切片,您必须使用它来切割目标切片。

此外,由于解码可能失败(无效的输入),您还应该检查返回的错误。

另外,由于不能保证给定的输入将产生一个使用的32位块的倍数的输出,所以传递 flush=true 来消耗给定的输入切片(而不是等待更多输入)。

最终的修正代码:

s := []byte("Hello, playground")

maxlen := ascii85.MaxEncodedLen(len(s))

dst := make([]byte, maxlen)
n := ascii85.Encode(dst, s)
dst = dst[:n]
fmt.Println(string(dst))

dst2 := make([]byte, maxlen)
n, _, err := ascii85.Decode(dst2, dst, true)
if err != nil {
	panic(err)
}
dst2 = dst2[:n]
fmt.Println(string(dst2))

Go Playground 上运行代码会输出:

87cURD_*#MCghU%Ec6)<A,
Hello, playground
英文:

ascii85.MaxEncodedLen() returns the maximum number of output bytes for the given number of input bytes. You may use this upper estimation.

The actual number of bytes used / written is returned ascii85.Encode(). If you passed a bigger slice to Encode(), you must use this to slice the destination slice, bytes beyond this are "garbage".

Same goes for ascii85.Decode(): it returns the number of written bytes, you must use that to slice the destination if you passed a bigger slice.

Also since decoding may fail (invalid input), you should also check the returned error.

Also since it's not guaranteed the given input will result in an output that is a multiple of the used 32-bit blocks, pass flush=true to consume the given input slice (and not wait for more input).

The final, corrected code:

s := []byte(&quot;Hello, playground&quot;)

maxlen := ascii85.MaxEncodedLen(len(s))

dst := make([]byte, maxlen)
n := ascii85.Encode(dst, s)
dst = dst[:n]
fmt.Println(string(dst))

dst2 := make([]byte, maxlen)
n, _, err := ascii85.Decode(dst2, dst, true)
if err != nil {
	panic(err)
}
dst2 = dst2[:n]
fmt.Println(string(dst2))

Which outputs (try it on the Go Playground):

87cURD_*#MCghU%Ec6)&lt;A,
Hello, playground

答案2

得分: 2

System.Text.ASCIIEncoding和encoding/ascii85包执行不同的功能。System.Text.ASCIIEncoding将文本编码为ASCII,将ASCII范围之外的字符替换为?。encoding/ascii85包将二进制数据编码为ascii85,也称为base85。

以下Go函数复制了问题中的C#函数:

func StrToByteArray(str string) []byte {
    var result []byte
    for _, r := range str {
        if r >= utf8.RuneSelf {
            r = '?'
        }
        result = append(result, byte(r))
    }
    return result
}

如果你知道字符串只包含ASCII字符,那么可以使用conversion来完成:

func StrToByteArray(str string) []byte { return []byte(str) }
英文:

System.Text.ASCIIEncoding and the encoding/ascii85 package do different things. System.Text.ASCIIEncoding encodes text to ASCII by replacing characters outside the ASCII range with ?. The encoding/ascii85 package encodes binary data to ascii85, a.k.a. base85.

The following Go function replicates the C# function in the question:

func StrToByteArray(str string) []byte {
	var result []byte
	for _, r := range str {
		if r &gt;= utf8.RuneSelf {
			r = &#39;?&#39;
		}
		result = append(result, byte(r))
	}
	return result
}

If you know that the string only contains ASCII characters, then a conversion will do the trick:

func StrToByteArray(str string) []byte { return []byte(str) }

huangapple
  • 本文由 发表于 2021年10月8日 21:28:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/69496647.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定