密码加密

几乎每天笔者们都不得不记住许多不同的密码——信用卡的密码,门禁密码等等。这些密码可以用一种方法记录下来,并且不会被犯罪分子利用吗?

假设我们有一张密码为3451的LISA信用卡,它的密码可以像这样被编码:

  1. a b c d e f g h i j k l m n o p q r s t u v w x y z
  2. 1 0 5 3 4 3 2 7 2 5 4 1 9 4 9 6 3 4 1 4 1 2 7 8 5 0 lisa

这样密码就可以写在一张纸上,即使这张纸落在他人手上,密码也是安全的。

我们如何解码信息呢?用来加密密码的密钥是公开的——因此我们可以很容易地读出密码(3451)–试试看!

我们很容易的就可以构造一个用来执行加密的函数encode(Pin,Password)[1]

  1. encode(Pin, Password) ->
  2. Code = {nil,nil,nil,nil,nil,nil,nil,nil,nil,
  3. nil,nil,nil,nil,nil,nil,nil,nil,nil,
  4. nil,nil,nil,nil,nil,nil,nil,nil},
  5. encode(Pin, Password, Code).
  6.  
  7. encode([], _, Code) ->
  8. Code;
  9. encode(Pin, [], Code) ->
  10. io:format("Out of Letters~n",[]);
  11.  
  12. encode([H|T], [Letter|T1], Code) ->
  13. Arg = index(Letter) + 1,
  14. case element(Arg, Code) of
  15. nil ->
  16. encode(T, T1, setelement(Arg, Code, index(H)));
  17. _ ->
  18. encode([H|T], T1, Code)
  19. end.
  20.  
  21. index(X) when X >= $0, X =< $9 ->
  22. X - $0;
  23.  
  24. index(X) when X >= $A, X =< $Z ->
  25. X - $A.

我们看一下以下的例子:

  1. > pin:encode("3451","DECLARATIVE").
  2. {nil,nil,5,3,4,nil,nil,nil,nil,nil,nil,1,nil,nil,nil,
  3. nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}

我们现在使用随机数来替换没有被填充的nil元素:

  1. print_code([], Seed) ->
  2. Seed;
  3.  
  4. print_code([nil|T], Seed) ->
  5. NewSeed = ran(Seed),
  6. Digit = NewSeed rem 10,
  7. io:format("~w ",[Digit]),
  8. print_code(T, NewSeed);
  9.  
  10. print_code([H|T],Seed) ->
  11. io:format("~w ",[H]),
  12. print_code(T, Seed).
  13.  
  14. ran(Seed) ->
  15. (125 * Seed + 1) rem 4096.

然后我们需要一些小函数将所有东西连接在一起:

  1. test() ->
  2. title(),
  3. Password = "DECLARATIVE",
  4. entries([{"3451",Password,lisa},
  5. {"1234",Password,carwash},
  6. {"4321",Password,bigbank},
  7. {"7568",Password,doorcode1},
  8. {"8832",Password,doorcode2},
  9. {"4278",Password,cashcard},
  10. {"4278",Password,chequecard}]).
  11.  
  12. title() ->
  13. io:format("a b c d e f g h i j k l m \
  14. n o p q r s t u v w x y z~n",[]).
  15.  
  16. entries(List) ->
  17. {_,_,Seed} = time(),
  18. entries(List, Seed).
  19.  
  20. entries([], _) -> true;
  21.  
  22. entries([{Pin,Password,Title}|T], Seed) ->
  23. Code = encode(Pin, Password),
  24. NewSeed = print_code(tuple_to_list(Code), Seed),
  25. io:format(" ~w~n",[Title]),
  26. entries(T, NewSeed).

最后我们可以运行这个程序了:

  1. 1> pin:test().
  2. a b c d e f g h i j k l m n o p q r s t u v w x y z
  3. 1 0 5 3 4 3 2 7 2 5 4 1 9 4 9 6 3 4 1 4 1 2 7 8 5 0 lisa
  4. 9 0 3 1 2 5 8 3 6 7 0 4 5 2 3 4 7 6 9 4 9 2 7 4 9 2 carwash
  5. 7 2 2 4 3 1 2 1 8 3 0 1 5 4 1 0 5 6 5 4 3 0 3 8 5 8 bigbank
  6. 1 0 6 7 5 7 6 9 4 5 4 8 3 2 1 0 7 6 1 4 9 6 5 8 3 4 doorcode1
  7. 1 4 3 8 8 3 2 5 6 1 4 2 7 2 9 4 5 2 3 6 9 4 3 2 5 8 doorcode2
  8. 7 4 7 4 2 5 6 5 8 5 8 8 9 4 7 6 5 0 1 2 9 0 9 6 3 8 cashcard
  9. 7 4 7 4 2 7 8 7 4 3 8 8 9 6 3 8 5 2 1 4 1 2 1 4 3 4 chequecard
  10. true

之后这些信息可以用很小的字体打印出来,粘在一张邮票的背后,藏在你的领带里面[2]