~telemachus/Exercism

392885548959505a17ef8731a06b37a972bdd1df — Peter Aronoff 5 months ago 1ff6a54
Atbash cipher
A go/atbash-cipher/.exercism/config.json => go/atbash-cipher/.exercism/config.json +37 -0
@@ 0,0 1,37 @@
{
  "blurb": "Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East.",
  "authors": [
    "zilkey"
  ],
  "contributors": [
    "alebaffa",
    "bitfield",
    "ekingery",
    "ferhatelmas",
    "hilary",
    "kytrinyx",
    "leenipper",
    "petertseng",
    "robphoenix",
    "sebito91",
    "strangeman",
    "tleen",
    "tompao"
  ],
  "files": {
    "solution": [
      "atbash_cipher.go"
    ],
    "test": [
      "atbash_cipher_test.go"
    ],
    "example": [
      ".meta/example.go"
    ],
    "editor": [
      "cases_test.go"
    ]
  },
  "source": "Wikipedia",
  "source_url": "http://en.wikipedia.org/wiki/Atbash"
}

A go/atbash-cipher/.exercism/metadata.json => go/atbash-cipher/.exercism/metadata.json +1 -0
@@ 0,0 1,1 @@
{"track":"go","exercise":"atbash-cipher","id":"7115dba7a4d545ef84e71780b66f814b","url":"https://exercism.org/tracks/go/exercises/atbash-cipher","handle":"telemachus","is_requester":true,"auto_approve":false}
\ No newline at end of file

A go/atbash-cipher/HELP.md => go/atbash-cipher/HELP.md +40 -0
@@ 0,0 1,40 @@
# Help

## Running the tests

To run the tests run the command `go test` from within the exercise directory.

If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:

    go test -v --bench . --benchmem

Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.

## Submitting your solution

You can submit your solution using the `exercism submit atbash_cipher.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.

It's possible to submit an incomplete solution which allows you to:

- See how others have completed the exercise
- Request help from a mentor

## Need to get help?

If you'd like help solving the exercise, check the following pages:

- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)

Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.

To get help if you're having trouble, you can use one of the following resources:

- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)
\ No newline at end of file

A go/atbash-cipher/README.md => go/atbash-cipher/README.md +61 -0
@@ 0,0 1,61 @@
# Atbash Cipher

Welcome to Atbash Cipher on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.

## Instructions

Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East.

The Atbash cipher is a simple substitution cipher that relies on
transposing all the letters in the alphabet such that the resulting
alphabet is backwards. The first letter is replaced with the last
letter, the second with the second-last, and so on.

An Atbash cipher for the Latin alphabet would be as follows:

```text
Plain:  abcdefghijklmnopqrstuvwxyz
Cipher: zyxwvutsrqponmlkjihgfedcba
```

It is a very weak cipher because it only has one possible key, and it is
a simple mono-alphabetic substitution cipher. However, this may not have
been an issue in the cipher's time.

Ciphertext is written out in groups of fixed length, the traditional group size
being 5 letters, leaving numbers unchanged, and punctuation is excluded.
This is to make it harder to guess things based on word boundaries.

## Examples

- Encoding `test` gives `gvhg`
- Encoding `x123 yes` gives `c123b vh`
- Decoding `gvhg` gives `test`
- Decoding `gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt` gives `thequickbrownfoxjumpsoverthelazydog`

## Source

### Created by

- @zilkey

### Contributed to by

- @alebaffa
- @bitfield
- @ekingery
- @ferhatelmas
- @hilary
- @kytrinyx
- @leenipper
- @petertseng
- @robphoenix
- @sebito91
- @strangeman
- @tleen
- @tompao

### Based on

Wikipedia - http://en.wikipedia.org/wiki/Atbash
\ No newline at end of file

A go/atbash-cipher/atbash_cipher.go => go/atbash-cipher/atbash_cipher.go +25 -0
@@ 0,0 1,25 @@
package atbash

import (
	"strings"
)

func Atbash(s string) string {
	var atbash strings.Builder
	for _, b := range []byte(s) {
		// This leaves an unwanted space at the end of the string. Trim that off
		// later.
		if atbash.Len()%6 == 5 {
			atbash.WriteByte(' ')
		}
		switch {
		case b >= 'a' && b <= 'z':
			atbash.WriteByte('z' - b + 'a')
		case b >= 'A' && b <= 'Z':
			atbash.WriteByte('z' - b + 'A')
		case b >= '0' && b <= '9':
			atbash.WriteByte(b)
		}
	}
	return strings.TrimSuffix(atbash.String(), " ")
}

A go/atbash-cipher/atbash_cipher.go.1 => go/atbash-cipher/atbash_cipher.go.1 +29 -0
@@ 0,0 1,29 @@
package atbash

import "strings"

const (
	plain  = "abcdefghijklmnopqrstuvwxyz123456789"
	cipher = "zyxwvutsrqponmlkjihgfedcba123456789"
)

func Atbash(s string) string {
	bs := make([]byte, 0, len(s))
	kept := 0
	s = strings.ToLower(s)

	for _, b := range []byte(s) {
		n := strings.IndexByte(plain, b)
		if n == -1 {
			continue
		}
		// This adds an unwanted space when kept == 0. Trim that off
		// later rather than add a test if keep == 0 to every loop.
		if kept%5 == 0 {
			bs = append(bs, ' ')
		}
		bs = append(bs, cipher[n])
		kept++
	}
	return strings.TrimPrefix(string(bs), " ")
}

A go/atbash-cipher/atbash_cipher_test.go => go/atbash-cipher/atbash_cipher_test.go +25 -0
@@ 0,0 1,25 @@
package atbash

import "testing"

func TestAtbash(t *testing.T) {
	for _, test := range tests {
		actual := Atbash(test.s)
		if actual != test.expected {
			t.Errorf("Atbash('%s'): expected '%s', actual '%s'", test.s, test.expected, actual)
		}
	}
}

func BenchmarkAtbash(b *testing.B) {
	if testing.Short() {
		b.Skip("skipping benchmark in short mode.")
	}
	for i := 0; i < b.N; i++ {

		for _, test := range tests {
			Atbash(test.s)
		}

	}
}

A go/atbash-cipher/cases_test.go => go/atbash-cipher/cases_test.go +61 -0
@@ 0,0 1,61 @@
package atbash

// Source: exercism/problem-specifications
// Commit: dda678b atbash-cipher: Apply new "input" policy
// Problem Specifications Version: 1.1.0

type atbashTest struct {
	s        string
	expected string
}

var tests = []atbashTest{
	{
		s:        "yes",
		expected: "bvh",
	},
	{
		s:        "no",
		expected: "ml",
	},
	{
		s:        "OMG",
		expected: "lnt",
	},
	{
		s:        "O M G",
		expected: "lnt",
	},
	{
		s:        "mindblowingly",
		expected: "nrmwy oldrm tob",
	},
	{
		s:        "Testing,1 2 3, testing.",
		expected: "gvhgr mt123 gvhgr mt",
	},
	{
		s:        "Truth is fiction.",
		expected: "gifgs rhurx grlm",
	},
	{
		s:        "The quick brown fox jumps over the lazy dog.",
		expected: "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt",
	},
	{
		s:        "exercism",
		expected: "vcvix rhn",
	},
	{
		s:        "anobstacleisoftenasteppingstone",
		expected: "zmlyh gzxov rhlug vmzhg vkkrm thglm v",
	},
	{
		s:        "testing123testing",
		expected: "gvhgr mt123 gvhgr mt",
	},
	{
		s:        "thequickbrownfoxjumpsoverthelazydog",
		expected: "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt",
	},
}

A go/atbash-cipher/go.mod => go/atbash-cipher/go.mod +3 -0
@@ 0,0 1,3 @@
module atbash

go 1.16