Go语言字符串处理:轻松玩转多语言与加密技巧

Go语言字符串处理:轻松玩转多语言与加密技巧

在当今全球化的开发环境中,处理多语言文本和实现基本的加密功能是每个开发者必备的技能。Go语言以其简洁、高效和强大的标准库,成为处理字符串和多语言支持的理想选择。无论是处理简单的字符串操作,还是实现复杂的加密算法,Go都能轻松应对。本文将带你深入探索Go语言中的字符串处理技巧,从基础操作到多语言支持,再到凯撒加密和ROT13算法的实现,让你快速掌握这些实用技能。

本文全面解析Go语言中的字符串处理技术,涵盖以下内容: 1. 字符串基础:声明、字面值、原始字符串字面值的使用。 2. 字符与编码:Unicode、rune、byte的区别与应用。 3. 多语言支持:UTF-8编码的处理与多字节字符的解码。 4. 加密技巧:凯撒加密和ROT13算法的实现与优化。

实战示例:通过代码示例演示如何高效处理多语言文本和实现加密功能。

无论你是初学者还是有一定经验的开发者,本文都能帮助你快速掌握Go语言中字符串处理的核心技巧,并应用于实际开发中。

多语言文本

声明字符串

  • 声明字符串:
peace := "peace"
var peace = "peace"
var peace string = "peace"
  • 字符串的零值:var blank string

字符串字面值/原始字符串字面值

  • 字符串字面值可以包含转义字符,例如\n
  • 但如果你确实想得到\n而不是换行的话,可以使用`来代替“,这叫做原始字符串字面值。
fmt.Println("peace be upon you\nupon you be peace")
fmt.Println(`strings can span multiple lines with the \n escape sequence`)

fmt.Println(`
peace be upon you
upon you be peace`)

小测试

  • 如果你想输出C:\go,那么应该使用字符串字面值还是原始字符串字面值。
  • 字符串字面值:string literal
  • 原始字符串字面值:raw string literal

字符,code points,runes,bytes

  • Unicode联盟为超过100万个字符分配了相应的数值,这个数叫做code point。
  • 例如:65代表A,128515 代表 一个表情字符
  • 为了表示这样的unicode code point,Go语言提供了rune这个类型,它是int32的一个类型别名。
  • 而byte是uint8类型的别名,目的是用于二进制数据。
  • byte倒是可以表示由ASCII定义的英语字符,它是Unicode的一个子集(共128个字符)

类型别名

  • 类型别名就是同一个类型的另一个名字。
  • 所以,rune和int32可以互换使用。
  • 也可以自定义类型别名,语法如下:
type byte = uint8
type rune = int32

打印

  • 如果想打印字符而不是数值,使用%c格式化动词
  • 任何整数类型都可以使用%c打印,但是rune意味着该数值表示了一个字符
package main

import (
 "fmt"
)

func main() {
 fmt.Println("peace be upon you\nupon you be peace")
 fmt.Println(`strings can span multiple lines with the \n escape sequence`)

 fmt.Println(`
 peace be upon you
 upon you be peace`)

 var pi rune = 960
 var alpha rune = 940
 var omega rune = 969
 var bang byte = 33

 fmt.Printf("%v %v %v %v\n", pi, alpha, omega, bang)
 // 将会打印出 code point 的值

 fmt.Printf("%c%c%c%c\n", pi, alpha, omega, bang)
 // 将会打印出 字符
}

运行

Code/go/started via 🐹 v1.20.3 via 🅒 base 
➜ go run main.go
peace be upon you
upon you be peace
strings can span multiple lines with the \n escape sequence

        peace be upon you
        upon you be peace
960 940 969 33
πάω!

Code/go/started via 🐹 v1.20.3 via 🅒 base 
➜ 

字符

  • 字符字面值使用‘’括起来。例如:’A’
  • 如果没指定字符类型的话,那么Go会推断它的类型为rune
  • 这里的grade仍然包含一个数值,本例中就是65,它是A的code point。
  • 字符字面值也可以用byte类型:var star byte = '*'
var grade rune
grade := 'A'
var grade1 = 'A'
var grade2 rune = 'A'

小测试

  • ASCII编码里包含多少个字符?
  • byte和rune分别是哪个类型的别名?
  • *,é,的code point分别是多少?

string

  • 可一个给某个变量赋予不同的string值,但是string本身是不可变的
peace := "shalom"
peace = "salam"

例子二

package main

import (
 "fmt"
)

func main() {
 message := "shalom"
 c := message[5]
 fmt.Printf("%c\n", c) // m

 message[5] = 'd' // 报错 cannot assign to message[5]
}

小测试

  • 写个程序,打印出shalom的每个字符,每个字符独占一行。

Caesar cipher凯撒加密法

  • 对于加密信息,一种简单有效的办法就是把每个字母都移动固定长度的位置。
  • 例如:a -> d,b -> e
package main

import (
 "fmt"
)

func main() {
 c := 'a'
 c = c + 3
 fmt.Printf("%c\n", c)

 if c > 'z' {
  c = c - 26
 }
 fmt.Printf("%c\n", c)
}

小测试

  • 这个语句的作用是什么?c = c - 'a' + ‘A’
  • 如果 c 是 ‘g’,那么c最后的结果是什么?

ROT13

  • ROT13(旋转13)是凯撒密码在20世纪的变体。
  • 它会把字母替换成+13后的对应的字母。

Go的内置函数

  • len是 Go 语言的一个内置函数。
message := "uv vagreangvbany fcnpr fgngvba"
fmt.Println(len(message))
  • 本例中len返回message所占的byte数。
  • Go有很多内置函数,它们不需要import

UTF-8

  • Go中的字符串是用UTF-8编码的,UTF-8是Unicode CodePoint的几种编码之一。
  • UTF-8是一种有效率的可变长度的编码,每个code point可以是8位、16位或32位的。
  • 通过使用可变长度编码,UTF-8使得从ASCII的转换变得简单明了,因为ASCII字符与其UTF-8编码的对应字符是相同的。
  • UTF-8是万维网的主要字符编码。它是由Ken Thompson于1992年发明的,他是Go语言的设计者之一。

ROT13

package main

import (
 "fmt"
)

func main() {
 message := "uv vagreangvbany fcnpr fgngvba"

 for i := 0; i < len(message); i++ {
  c := message[i]
  if c >= 'a' && c <= 'z' {
   c = c + 13
   if c > 'z' {
    c = c - 26
   }
  }
  fmt.Printf("%c", c)
 }
}
  • 本例中,程序访问的是message这个字符串的每个字节(8位),没有考虑多字节的情况(16、32位)。
  • 如何支持西班牙语、俄语、汉语等?
  • 把字符解码成rune类型,然后再进行操作。
  • 使用utf-8包,它提供可以按rune计算字符串长度的方法。
  • DecodeRuneInString 函数会返回第一个字符,以及字符所占的字节数。
  • 所以Go里的函数可以返回多个值。
package main

import (
 "fmt"
 "unicode/utf8"
)

func main() {
 question := "español?"
 fmt.Println(len(question), "bytes")
 fmt.Println(utf8.RuneCountInString(question))

 c, size := utf8.DecodeRuneInString(question)
 fmt.Printf("First rune: %c %v bytes\n", c, size)
}

range

  • 使用range关键字,可以遍历各种集合。
package main

import (
 "fmt"
)

func main() {
 question := "español ?"

 for i, c := range question {
  fmt.Printf("%v %c\n", i, c)
 }

  for _, c := range question {
  fmt.Printf("%c\n", c)
 }
}

作业题

  1. L fdph, L vdz, L frqtxhuhg,每个字母向前移动3个位置,能得到什么字符串?

  2. 把西班牙语 “Hola Estación Espacial Internacional”用ROT13进行加密

  3. 使用range关键字
  4. 带重音符号的字母要保留

总结

Go语言为字符串处理提供了强大而灵活的工具,无论是基础的字符串操作,还是复杂的多语言支持和加密功能,都能轻松实现。通过本文的学习,你应该已经掌握了以下技能: - 如何声明和处理字符串,包括多行字符串和原始字符串字面值。 - 理解Unicode、rune和byte的区别,并能够处理多语言文本。 - 实现凯撒加密和ROT13算法,为文本加密提供基础支持。 - 使用Go的内置函数和标准库(如utf8包)高效处理字符串。

这些技能不仅能够帮助你在日常开发中高效处理字符串,还能为你在国际化应用和基础加密需求中提供有力支持。希望本文能成为你Go语言学习路上的实用指南,助你轻松玩转字符串处理!

全部评论(0)