{"action":"created","issue":{"url":"https://api.github.com/repos/sympy/sympy/issues/10317","labels_url":"https://api.github.com/repos/sympy/sympy/issues/10317/labels{/name}","comments_url":"https://api.github.com/repos/sympy/sympy/issues/10317/comments","events_url":"https://api.github.com/repos/sympy/sympy/issues/10317/events","html_url":"https://github.com/sympy/sympy/issues/10317","id":123895521,"number":10317,"title":"Extend vigenère in crypto to accept repetitions in keys","user":{"login":"ec-m","id":10234559,"avatar_url":"https://avatars.githubusercontent.com/u/10234559?v=3","gravatar_id":"","url":"https://api.github.com/users/ec-m","html_url":"https://github.com/ec-m","followers_url":"https://api.github.com/users/ec-m/followers","following_url":"https://api.github.com/users/ec-m/following{/other_user}","gists_url":"https://api.github.com/users/ec-m/gists{/gist_id}","starred_url":"https://api.github.com/users/ec-m/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ec-m/subscriptions","organizations_url":"https://api.github.com/users/ec-m/orgs","repos_url":"https://api.github.com/users/ec-m/repos","events_url":"https://api.github.com/users/ec-m/events{/privacy}","received_events_url":"https://api.github.com/users/ec-m/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":20,"created_at":"2015-12-25T19:24:42Z","updated_at":"2015-12-29T01:56:24Z","closed_at":null,"body":"In line 369 of function `encipher_vigenere`, which is part of `crypto.py` the method `uniq` from utilities.iterables is used to return an iterator of the key-phrase without possible spaces in the key. However, `uniq` will return an iterator with only unique characters of the key. Therefore, if one uses a key such as \"cool\", `uniq` returns \"col\" and the function will hence encrypt in a wrong way.\r\n\r\nExample: `encipher_vigenere(\"wow\", \"cool\")` returns \"YCH\". However, the right result would actually be \"YCK\".\r\n\r\nAlso, instead of using `capitalize` on each character of the key or the plaintext (see lines 370 or 373) we could also simplify the problem by using `key.upper` or `pt.upper`.\r\n\r\nI would volunteer to fix this and if I am assuming right and `uniq` is used wrong also in other crypto functions such as `encipher_bifid5` or `bifid5_square` I could also fix these functions."},"comment":{"url":"https://api.github.com/repos/sympy/sympy/issues/comments/167697302","html_url":"https://github.com/sympy/sympy/issues/10317#issuecomment-167697302","issue_url":"https://api.github.com/repos/sympy/sympy/issues/10317","id":167697302,"user":{"login":"smichr","id":90703,"avatar_url":"https://avatars.githubusercontent.com/u/90703?v=3","gravatar_id":"","url":"https://api.github.com/users/smichr","html_url":"https://github.com/smichr","followers_url":"https://api.github.com/users/smichr/followers","following_url":"https://api.github.com/users/smichr/following{/other_user}","gists_url":"https://api.github.com/users/smichr/gists{/gist_id}","starred_url":"https://api.github.com/users/smichr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smichr/subscriptions","organizations_url":"https://api.github.com/users/smichr/orgs","repos_url":"https://api.github.com/users/smichr/repos","events_url":"https://api.github.com/users/smichr/events{/privacy}","received_events_url":"https://api.github.com/users/smichr/received_events","type":"User","site_admin":false},"created_at":"2015-12-29T01:56:24Z","updated_at":"2015-12-29T01:56:24Z","body":"> I interpret \"The repeated letters of the key are always ignored.\" to mean,\r\n> for example, that the key \"AAC\" is replaced by \"AC\".\r\n\r\n<smile> That is self evident since these are your own words, not those of the wikipedia article. \r\n\r\nWhat the article is saying is that each letter of the `key string` corresponds to one of 26 `keys`; repeated letters in the `key string` each use the same `key`. In fact, in the Kasiski analysis section it says \"This means that the key length could be 30 ... characters long.\"  This would be impossible if only the unique letters in the `key string` were used.\r\n\r\nThere is a good reason to allow repeated letters in the `key string`: if you don't, you end up with a smaller `key phrase` but the more unbreakable `key string` is the one that approaches a random sequence of the numbers letters. `abracadabra` is 11 chars long but using the current implementation would condense down to `abrcd`; at the extreme, a random `key string` as long as the text to be encypted would necessarily reduce to only 26 characters and the latter will be much easier to break.\r\n\r\nIf you are not agreeable to changing the default behavior, a keyword to allow for not removing repeats is fine with me. Since we are so close to the initial release of this module I would prefer to redefine this aspect rather than make the non-traditional (based on the wiki reference) behavior be the default.\r\n\r\nThe following function might also be good to add:\r\n\r\n```python\r\n>>> def keystring(phrase, repeats=True):\r\n...   rv = ''.join(''.join(phrase.split()).upper())\r\n...   if repeats:\r\n...     return rv\r\n...   return ''.join(uniq(rv))\r\n...\r\n>>> keystring('a stitch in time saves nine')\r\n'ASTITCHINTIMESAVESNINE'\r\n>>> keystring('a stitch in time saves nine', 0)\r\n'ASTICHNMEV'\r\n>>>\r\n```"}}