Exemplo n.º 1
0
func BreakXorRepeating(ciphertext []byte, keysizes []int) ([]byte, error) {
	if len(ciphertext) == 0 {
		return nil, errors.New("empty ciphertext")
	}
	if len(keysizes) == 0 {
		return nil, errors.New("no keysizes given")
	}

	var bestScore = 0.0
	var plaintext []byte

	for _, size := range keysizes {
		split, _ := bytes.SplitIntoBlocks(ciphertext, size)
		transposed, err := blocks.Transpose(split)
		if err != nil {
			return nil, err
		}

		key := make([]byte, size)
		for i, block := range transposed {
			popular, _ := bytes.Popular(block, 1)
			key[i] = popular[0]
		}

		decrypted, _ := bytes.XorRepeatingKey(ciphertext, key)
		score := utils.EnglishScore(string(decrypted))

		if score > bestScore {
			plaintext = decrypted
			bestScore = score
		}
	}
	return plaintext, nil
}
Exemplo n.º 2
0
// Detect single-character XOR
func c4() (actual, expected Result) {
	expected = string([]byte{110, 79, 87, 0, 84, 72, 65, 84, 0, 84, 72, 69, 0, 80, 65, 82, 84, 89, 0, 73, 83, 0, 74, 85, 77, 80, 73, 78, 71, 42})

	input, err := ioutil.ReadFile("input/4.txt")
	if err != nil {
		panic(err)
	}

	lines := strings.Split(string(input), "\n")
	var bestScore = 0.0
	var plaintext string

	// Find the most popular byte in each line
	for i := 0; i < len(lines)-1; i++ {
		line, err := hex.DecodeString(lines[i])
		if err != nil {
			log.Println(err)
			continue
		}

		key, err := bytes.Popular(line, 1)
		if err != nil {
			log.Println(err)
			continue
		}

		decrypted, err := bytes.XorRepeatingKey(line, key)
		if err != nil {
			log.Println(err)
			continue
		}

		// Score each string for how likely it is English
		decryptedStr := string(decrypted)
		score := utils.EnglishScore(decryptedStr)
		if score > bestScore {
			bestScore = score
			plaintext = decryptedStr
		}
	}
	return plaintext, expected
}