/Test/Algorithms/vigenere.pas

http://github.com/alexvins/dwscript · Pascal · 65 lines · 45 code · 9 blank · 11 comment · 6 complexity · 01a1a444bbfb8487fb45e14511dc7d26 MD5 · raw file

  1. {
  2. Inspired from http://delphi.about.com/b/2010/08/30/vigenere-cipher-algorithm-delphi-implementation-comments-by-alan-lloyd.htm
  3. which looked arcane enough to be worthy of a unit test
  4. This implementation is rather fragile, don't reuse ;)
  5. }
  6. function Vigenere(src, key : String; encrypt : boolean) : String;
  7. begin
  8. const cOrdMinChar : integer = Ord('A');
  9. const cOrdMaxChar : integer = Ord('Z');
  10. const cCharRangeCount = cOrdMaxChar - cOrdMinChar + 1;
  11. var i, j, keyLen, keyInc, srcOrd, cryptOrd : integer;
  12. var srcA : String;
  13. keyLen := Length(key);
  14. SetLength(srcA, Length(src));
  15. if encrypt then begin
  16. // transfer only included characters to srcA for encryption
  17. j := 1;
  18. for i := 1 to Length(src) do begin
  19. case src[i] of
  20. 'A'..'Z': begin
  21. srcA[j] := src[i];
  22. j:=j+1;
  23. end;
  24. end;
  25. end;
  26. SetLength(srcA, j - 1);
  27. end;
  28. if encrypt then begin
  29. // encrypt to Result
  30. SetLength(Result, Length(srcA));
  31. for i := 1 to Length(srcA) do begin
  32. srcOrd := Ord(srcA[i]) - cOrdMinChar;
  33. keyInc := Ord(key[(i-1) mod keyLen + 1]) - cOrdMinChar;
  34. cryptOrd := ((srcOrd + keyInc) mod cCharRangeCount) + cOrdMinChar;
  35. Result[i] := Chr(cryptOrd);
  36. end;
  37. end else begin
  38. // Decrypt to Result
  39. SetLength(Result, Length(src));
  40. for i := 1 to Length(src) do begin
  41. srcOrd := Ord(src[i]) - cOrdMinChar;
  42. keyInc := Ord(key[(i-1) mod keyLen + 1]) - cOrdMinChar;
  43. cryptOrd := ((srcOrd - keyInc + cCharRangeCount) mod cCharRangeCount) + cOrdMinChar;
  44. // keyInc may be larger than srcOrd
  45. Result[i] := Chr(cryptOrd);
  46. end;
  47. end;
  48. end;
  49. const key : String = 'MYKEY';
  50. var buf : String;
  51. buf:=Vigenere('HELLO WORLD', key, True);
  52. PrintLn(buf);
  53. buf:=Vigenere(buf, key, False);
  54. PrintLn(buf);