# shortest code to encrypt a string

Using a language of your choice write a program that takes a string as an input, and returns the string encrypted.

# Algorithm:

You should assume that each character is always encoded in a byte and is ASCII-based. The extended ASCII codes are mapped to whatever is the default code page in use by the system.

You should encrypt the code in the following way: code of first character +1, code of second character +2, code of third character +3 .....

Extended ASCII codes are based on this table: http://www.asciitable.com/

Shortest code wins.

• If you're above 128 it's not ASCII. I have no idea what you're trying to say with your example of wrapping: please rewrite it to make it clear which values come from the plaintext and which come from the key stream. – Peter Taylor Feb 4 '14 at 20:59
• Is the requirement to jump past 0 when overflowing byte deliberate? (The successor to 255 for a byte is usually 0) – Sylwester Feb 4 '14 at 21:24
• Encryption algorithms that don't have keys don't seem rather useful. In fact this is just hardcoding one key for a substitution cipher. – Cruncher Feb 5 '14 at 13:49
• If you're above 255, it isn't even the OEM character set. Please read joelonsoftware.com/articles/Unicode.html when you get a chance. I re-read it every few years. :) – Charles Burns Feb 5 '14 at 16:38
• @user689 I edited the question. Let me know if you do agree with that or not. – Victor Stafusa Feb 5 '14 at 20:03

## GolfScript 201915 12

{0)255%:0+}%


This assigns a variable to the character 0, which allows us to not define it on the first iteration of the mapping. I love that you can do that in GolfScript! Each iteration of the mapping increments the 0 variable, and adds it to subsequent characters of the string (which is treated like an array).

This alternate 20-character GolfScript solution using zip encounters an interesting issue:

.,,]zip{~)255%+}%''+


Try it here. This standard online interpreter, however, treats zip differently for an array containing a string and an array. See this vs this. I'm not sure if an alternate version of Ruby or GolfScript is being used, or which one is considered canonical, but the second interpreter can be resolved with 2 characters:

.,,[\]zip{~)255%+}%''+


I also like a different solution for 23 characters:

1\{(@.@255%+\)@.}do]''+

• The first one gives me an error message? undefined method 'rightparen' for nil:NilClass – Gareth Feb 4 '14 at 23:11
• interesting - it works with this interpreter: copy.sh/golfscript/… – Ben Reich Feb 4 '14 at 23:14
• Hmmm. This is where I get the error; different versions of Ruby or Golfscript, maybe? – Gareth Feb 4 '14 at 23:17
• The more standard online interpreter (golfscript.apphb.com) treats zip differently with an array containing a string and an array. See copy.sh/golfscript/… vs golfscript.apphb.com/… – Ben Reich Feb 4 '14 at 23:19
• @Gareth the new 15-character solution is cooler, anyway, and works in both! :) – Ben Reich Feb 4 '14 at 23:37

# BrainFuck: 21

>,[+<[->+>+<<]>.>+>,]


Assumes EOF=zero

echo -n 'My secret password is 123456!' | beef encrypt.bf
==> N{#wjiym}*{mv36HJLNPR>

• Nice. And the code is encrypted too! – Pierre Arlaud Feb 5 '14 at 14:38
• "Obfuscated," not "encrypted." There is no secret key. – BlueRaja - Danny Pflughoeft Feb 5 '14 at 20:02

# C — 6756 49 characters

During compilation it might warn that q is missing a type...

q;main(p){for(;p=~getchar();)putchar(q++%255-p);}


Thanks to Josh for the significantly shorter rewrites!

$echo 'My secret password is 123456!' | ./_encrypt N{#wjiym}*{m����v3}�6HJLNPR>(  Confirm it handles the rollover from 255 to 1 correctly by encrypting 343 xs and checking for no xs in the output: $ echo xxxxxxx | sed -e 's/x/xxxxxxx/g' -e 's/x/xxxxxxx/g' | ./_encrypt | grep -o x | wc -l
0

• You can make this quite a bit shorter: q;main(p){for(;p>0;q*=q<255)putchar(++q+(p=getchar()));} – Josh Feb 4 '14 at 20:20
• Wow, I'm always amazed at what people can do with normally verbose languages! Is it okay to revise my submission using it? – user15259 Feb 4 '14 at 20:25
• @Gareth - I don't think that's what he means. If you encrypt and it gives 0, then "correct" it to 1, then accurate decryption isn't guaranteed. – user15259 Feb 4 '14 at 21:06
• You can test for EOF by ~p. And I think you can also make the condition p=~getchar() and then use ++q+~p (saving parentheses). – ugoren Feb 4 '14 at 21:25
• Using @ugoren's recommendations I can get it down to 49 characters, passing both test cases: q;main(p){for(;p=~getchar();)putchar(q++%255-p);} – Josh Feb 5 '14 at 1:59

# Befunge 98 - 15 bytes

:~+'U3*%1+,1+#@


Keeps a counter (starting at 0) and adds that to the ~ input. Then, computes 255 (as 85 * 3 in the form of 'U3*), then mods (%). Then, it adds 1 and prints it, then adds one to the counter, then uses # to skip over the @. At the end of the input, the IP goes the other way and hits the @, ending the program.

Alternatively, if your interpreter supports unicode, this 14 byte (13 char) solution works:

:~+'ÿ%1+,1+#@


Sample run (in command prompt, so some of the unicode characters are actually some ascii value):

This string will be encrypted using the predetermined method!2.7182818284590452353602874713526624


Output:

Ujlw%y{zrxr,äw{|1tx4zäzèÆèÅüü>öôèÉèDÖÄîHÖ£ÉÉÆóöó₧¢íÖÖVñ¥¡ó¬á^pmwrzu|v~yÇ}⌂ä|üâüâåàëäçÄÄîÉïÄæÅöòÆò

• @ArlaudPierre What are you talking about? Befunge is my favorite programming language. – Justin Feb 5 '14 at 17:08
• Is ÿ considered one or two bytes? Its value is 255 which is within one unsigned byte... – Justin Feb 6 '14 at 1:21

## J, 21 characters

a.{~1+256|(+i.@#)a.i.


Usage (borrowing Yimin's test text):

   a.{~1+256|(+i.@#)a.i.'My secret password is 123456!'
N{#wjiym}*{m????v3}?6HJLNPR>


# Python2.7 (67 chars)

import sys;print''.join([chr((ord(x)+1)%256)for x in sys.argv[1]])


## JavaScript, 90c

t.split("").map(function(c,a){return String.fromCharCode(c.charCodeAt(0)+a+1)}).join("")
[].map.call(t,function(c,a){return String.fromCharCode(c.charCodeAt(0)+a%255+1)}).join("")


Fiddledee

• Your code doesn't wrap after 255 chars, it needs to be this: .split("").map(function(c,a){return String.fromCharCode(c.charCodeAt(0)+a%255+1)}).join("") – A.M.K Feb 4 '14 at 23:51
• You can also do this and save 1 character: [].map.call(t,function(c,a){return String.fromCharCode(c.charCodeAt(0)+a%255+1)}).join("") – A.M.K Feb 5 '14 at 0:22
• @A.M.K: Nice.. ducktyping the string, very clever! Forgot the modulus -.- – micha Feb 5 '14 at 0:39
• @micha I will try to understand what you write later. But I can see that you can drop that 0 in .charCodeAt(0) and save one char. – Gaurang Tandon Feb 7 '14 at 16:00
• You don't need the 0 in c.charCodeAt and in EcmaScript 6 (supported in Firefox & Google Chrome), you can make it even shorter: [].map.call(t,(c,a)=>String.fromCharCode(c.charCodeAt()+a%255+1)}).join("") – Toothbrush Feb 22 '14 at 14:34

# Javascript/JScript: 72 to 105 chars

Here is a Javascript/JScript attempt at making a version of this code.

I'm aware that there is another Javascript code, but that one relies on recent Javascript implementations.

That code is invalid in ie8< without polyfills.

Here is my version:

function $(c){for(var i=0,l=c.length,o='';i<l;o+=String.fromCharCode(c.charCodeAt(i++)+i&255));return o;} //function call, 105 chars, absolutely valid! function$(c){for(i=0,l=c.length,o='';i<l;o+=String.fromCharCode(c.charCodeAt(i++)+i&255));return o;}
//function call, no var keyword, 101 chars, completely valid!

function $(c){for(i=0,l=c.length,o='';i<l;o+=String.fromCharCode(c.charCodeAt(i++)+i));return o;} //function call, 97 chars, most likely invalid! c='';//here goes input, output is in var o, dont count this line for(i=0,l=c.length,o='';i<l;o+=String.fromCharCode(c.charCodeAt(i++)+i&255)); //no function call, input goes to var c, 77 chars of pure working code! valid for sure! c='';//here goes input, output is in var o, dont count this line for(i=0,l=c.length,o='';i<l;o+=String.fromCharCode(c.charCodeAt(i++)+i)); //no function call, input goes to var c, no char wrapping after 255, 73 chars of probably invalid code  @toothbrush gave me this answer: i=0;while(i<c.length)c[i]=String.fromCharCode(c.charCodeAt(i++)+i%255+1)  It changes the original string and is only 72 bytes! I don't know why he has %255+1 in the end when &255 does the same job, is faster and shorter. But I will keep the original answer intact. Consider this and test it with a Javascript/JScript interpreter. I know that the 73 char version and the 97 char function call version will be invalid, but its still here! If you will be using the code in a production environment (website), use the 105 chars long and consider changing the function name to something else (or you might have problems with jQuery and MooTools). • The 73 character version can be even shorter: i=0;while(i<c.length)c[i]=String.fromCharCode(c.charCodeAt(i++)+i). To properly handle the wrapping of the numbers: i=0;while(i<c.length)c[i]=String.fromCharCode(c.charCodeAt(i++)+i%255+1) - this version is still shorter than the current version! Both modify the original string. – Toothbrush Feb 22 '14 at 14:45 • @Ismael Miguel, No offense, but this is a code golf website; the code isn't intended to ever be used. Therefore browser compatibility isn't a consideration. – A.M.K Apr 14 '14 at 19:50 • @A.M.K Does it work? Is it short? – Ismael Miguel Apr 14 '14 at 20:39 • @IsmaelMiguel, Yes, but you said I'm aware that there is another Javascript code, but that one relies on recent Javascript implementations. That is a bad thing!!!. All I'm saying is that since this is a code golf question, that isn't a bad thing. I've even seen answers that use features that haven't been implemented yet! – A.M.K Apr 17 '14 at 0:40 • Yes, but the upvotes are based on code beauty, not functionality. Basically: they are upvoting code that MIGHT not work for an undefined time. – Ismael Miguel Apr 17 '14 at 17:17 # Python3 (99 chars) e='' i=0 for c in __import__("sys").argv[1]: i=(i+1)%255 e+=chr(ord(c)+i) print(e)  ## Example python encrypt.py password outputs qcvw|uyl • The output for password should be qcvw|uyl. – Gareth Feb 4 '14 at 23:13 • Yeah, i fixed that, was a little bit to hectic :) – klingt.net Feb 4 '14 at 23:15 • You can remove the from sys... part by doing for c in __import__("sys").argv[1]. – SimonT Feb 5 '14 at 3:14 ## CoffeeScript, 73 64 chars t.replace /./g,(c,a)->String.fromCharCode c.charCodeAt()+a%255+1 [].map.call(t,(c,a)->String.fromCharCode c.charCodeAt(0)+a%255+1).join "" Example: "Test string".replace /./g,(c,a)->String.fromCharCode c.charCodeAt()+a%255+1 outputs Ugvx%y{zrxr Coffee to Javascript converter (paste in right box): http://js2coffee.org/ As per Ismael Miguel's comments, this method should work in IE 5.5+. ## Ruby functional, 67 puts ARGV[0].bytes.map.with_index(1){|b,i|b+i%255}.map(&:chr).join  Example: $ ruby encrypt.rb password
=> qcvw|uyl

• A new user without the comment privilege suggested shortening the code to puts ARGV[0].bytes.map.with_index(1){|b,i|(b+i&255).chr}*''. I've rejected the edit as per our policy but you might want to review it and edit it in yourself and credit them. – Martin Ender Sep 3 '16 at 8:48

# Julia 51 (-4 if in place is allowed)

g(s)=([s.data[i]+=(i-1)%255+1 for i=1:length(s)];s)
g(s)=[s.data[i]+=(i-1)%255+1 for i=1:length(s)] # in place version
julia> g("a"^256) # ^ operator repeats strings
"bcdefghijklmnopqrstuvwxyz{|}~\x7f��������������������������������������������������������������������������������������������������������������������������������\0\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\e\x1c\x1d\x1e\x1f !\"#\$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_b"  • Note that 0 is not allowed as an encryptor, so in your example you shouldn't see a outputted. – user15259 Feb 4 '14 at 20:16 • Or maybe it is, once I reread the specs, it might be asking for a non-reversible encryption. – user15259 Feb 4 '14 at 21:09 • No I think you are right. I updated it, which adds a few letters. – gggg Feb 4 '14 at 21:57 ## GolfScript, 27 characters [.,,\]zip[{{+}*255%1+}/]''+  Hmmm...seems a bit long. Maybe I should stick to J. ## Haskell, 77C 59C import Data.Char e s=h s 1 h""_="" h(x:s)i=(chr(mod((ord x)+i)128)):h s(i+1)  v2 import Data.Char e s = map chr(zipWith(+)(map ord s)[1..])  I am assuming that input doesn't need to be on STDIN. Example run: *Main> e "hello" "igopt"  # Erlang: 60C Not the smallest or prettiest, but this one can be run standalone in the command line. Set T to your text. {S,_}=lists:mapfoldl(fun(C,I)->{C+I,(I+1)rem 255}end,1,T),S.  Yields: "qcvw|uyl" # Rebol, 58 chars s: input forall s[s/1: mod(index? s)+(to-integer s/1)256]s  Groovy, 53 Characters i=0;args[0].chars.collect{(char)it+(++i%255)}.join()  # Ruby, 45 39 bytes gets.chars{|c|putc(c.ord+$.)%256;$.+=1}  # Perl, 54 char $i=1;print map{chr((ord()+$i++)%256)}split//,$ARGV[0];


Example:

perl encrypt.pl password
> qcvw|uyl


# Dart, 68

f(s,{i=1})=>new String.fromCharCodes(s.runes.map((c)=>(c+i++)%255));


Example:

f('My secret password is 123456!');
> N{#wjiym}*{mv3}6HJLNPR>
`