Go 语言入门很简单:Go 实现凯撒密码(下)

简介: 在文本上使用凯撒密码来移动字符。调用 strings.Map 方法。

4 其他实现

package main
import (
  "errors"
  "fmt"
  "reflect"
  "regexp"
)
var TBL = []rune("abcdefghijklmnopqrstuvwxyz")
var CLUES = []string{"this", "the", "that"}
var (
  ErrLength = errors.New("invalid length")
  ErrChar = errors.New("invalid char")
  ErrNoClue = errors.New("no clue word")
  ErrShift = errors.New("invalid shift value")
)
func Encrypt(in string, sh int) (enc string, err error) {
  err = assert(in)
  if sh < 0 {
    err = ErrShift
  }
  if err != nil {
    return
  }
  enc = shift(in, sh)
  return
}
func Decrypt(in string) (dec string, sh int, err error) {
  err = assert(in)
  if err != nil {
    return
  }
  var hit bool = false 
  subin := subStr(in)
  for i := 0; i < len(CLUES); i++ {
    subclue := subStr(CLUES[i])
    for j := 0; j < len(subin)-len(subclue)+1; j++ {
      if reflect.DeepEqual(subin[j:j+1], subclue[0:len(subclue)-1]) {
        sh = subtract([]rune(in)[j], []rune(CLUES[i])[0])
        hit = true
        break
      }
    }
  }
  if !hit {
    err = ErrNoClue
    return
  }
  dec = shift(in, -sh)
  return
}
func assert(in string) (err error) {
  if regexp.MustCompile(`[^a-z\. \r\n]`).MatchString(in) {
    err = ErrChar
  } else if len(in) > 80 {
    err = ErrLength
  }
  return
}
func shift(in string, sh int) (out string) {
  for _, v := range in {
    if v == '.' || v == ' ' || v == '\r' || v == '\n' {
      out += string(v)
      continue
    }
    i := indexOf(TBL, v)
    len := len(TBL)
    var ii int = (i + sh) % len
    if ii < 0 {
      ii += len
    }
    if ii > len {
      ii -= len
    }
    out += string(TBL[ii])
  }
  return
}
func subtract(left rune, right rune) (out int) {
  l := indexOf(TBL, left)
  r := indexOf(TBL, right)
  out = l - r
  if out < 0 {
    out += len(TBL)
  }
  return
}
func subStr(in string) []int { 
  subin := make([]int, 0, 79) 
  for i := range in {
    if i > len(in)-2 {
      break
    }
    subin = append(subin, subtract([]rune(in)[i], []rune(in)[i+1]))
  }
  // return
  return subin
}
func indexOf(target []rune, searchChar rune) int {
  for i, v := range target {
    if v == searchChar {
      return i
    }
  }
  return -1
}
func main() {
  in := "xlmw mw xli tmgxyvi xlex m xsso mr xli xvmt."
  fmt.Printf("in : '%s'\n", in)
  out, sh, err := Decrypt(in)
  fmt.Printf("out: '%s'\n", out)
  fmt.Printf("sh : %d\n", sh)
  fmt.Printf("err: %v\n", err)
}

5 测试

package main
import (
  "fmt"
  "strings"
)
func caesar(r rune, shift int) rune {
  // Shift character by specified number of places.
  // ... If beyond range, shift backward or forward.
  s := int(r) + shift
  if s > 'z' {
    return rune(s - 26)
  } else if s < 'a' {
    return rune(s + 26)
  }
  return rune(s)
}
func main() {
  value := "test"
  fmt.Println(value)
  // Test the caesar method in a func argument to strings.Map.
  value2 := strings.Map(func(r rune) rune {
    return caesar(r, 18)
  }, value)
  value3 := strings.Map(func(r rune) rune {
    return caesar(r, -18)
  }, value2)
  fmt.Println(value2, value3)
  value4 := strings.Map(func(r rune) rune {
    return caesar(r, 1)
  }, value)
  value5 := strings.Map(func(r rune) rune {
    return caesar(r, -1)
  }, value4)
  fmt.Println(value4, value5)
  value = "exxegoexsrgi"
  result := strings.Map(func(r rune) rune {
    return caesar(r, -4)
  }, value)
  fmt.Println(value, result)
}

运行该程序:

test
lwkl test
uftu test
exxegoexsrgi attackatonce


6 总结

本文简单介绍了一个有意思的密码学中的凯撒密码,该算法是一种替换加密技术,并在 Go 代码中实现了该算法的加密和解密过程。

相关文章
|
2月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
235 4
|
3月前
|
Linux Go iOS开发
Go语言100个实战案例-进阶与部署篇:使用Go打包生成可执行文件
本文详解Go语言打包与跨平台编译技巧,涵盖`go build`命令、多平台构建、二进制优化及资源嵌入(embed),助你将项目编译为无依赖的独立可执行文件,轻松实现高效分发与部署。
|
2月前
|
Cloud Native 安全 Java
Go语言深度解析:从入门到精通的完整指南
🌟蒋星熠Jaxonic,Go语言探索者。深耕云计算、微服务与并发编程,以代码为笔,在二进制星河中书写极客诗篇。分享Go核心原理、性能优化与实战架构,助力开发者掌握云原生时代利器。#Go语言 #并发编程 #性能优化
404 43
Go语言深度解析:从入门到精通的完整指南
|
2月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
179 1
|
3月前
|
Cloud Native 安全 Java
Go语言深度解析:从入门到精通的完整指南
🌟 蒋星熠Jaxonic,执着的星际旅人,用Go语言编写代码诗篇。🚀 Go语言以简洁、高效、并发为核心,助力云计算与微服务革新。📚 本文详解Go语法、并发模型、性能优化与实战案例,助你掌握现代编程精髓。🌌 从goroutine到channel,从内存优化到高并发架构,全面解析Go的强大力量。🔧 实战构建高性能Web服务,展现Go在云原生时代的无限可能。✨ 附技术对比、最佳实践与生态全景,带你踏上Go语言的星辰征途。#Go语言 #并发编程 #云原生 #性能优化
|
4月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
382 0
|
4月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
245 0
|
4月前
|
Cloud Native Java 中间件
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
222 0
|
4月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
317 0
【Go语言入门100题】026 I Love GPLT (5 分) Go语言 | Golang
L1-026 I Love GPLT (5 分) Go语言|Golang 这道超级简单的题目没有任何输入。 你只需要把这句很重要的话 —— “I Love GPLT”——竖着输出就可以了。 所谓“竖着输出”,是指每个字符占一行(包括空格),即每行只能有1个字符和回车。
709 0