Сейчас на форуме: zds, 2nd, morgot, Rio, CDK123, tyns777, tihiy_grom (+5 невидимых)

 eXeL@B —› Программирование —› FunctionReverse
Посл.ответ Сообщение


Ранг: 756.3 (! !), 113thx
Активность: 0.610.05
Статус: Участник
Student

Создано: 18 февраля 2009 21:06 · Поправил: Isaev
· Личное сообщение · #1

Имеется функция:
Code:
  1.   Symb='ABEHKNRWXZ';
  2. Function CodeInverse(S:String):String;
  3. Var
  4.   N,M:Integer;
  5.   L:String;
  6. Begin
  7.   Result:='';
  8.   L:='';
  9.   M:=1;
  10.   For N:=1 To Length(S) Do
  11.     Begin
  12.       If N>2 Then M:=Von(Result[N-2],N)+Von(Result[N-1],N);
  13.       If M>6 Then
  14.         Begin
  15.           If S[N] In ['0'..'9','A','B'] Then Result:=Result+Chr(Von(S[N],N)+$30)
  16.                                         Else Result:=Result+Chr(N Mod 5+$30);
  17.         End
  18.              Else
  19.         Begin
  20.           If Not(S[N] In ['0'..'9']) Then Result:=Result+Chr(Von(S[N],N)+$30)
  21.                                      Else Result:=Result+Chr(N Mod 5+$30);
  22.         End;
  23.       L:=L+IntToStr(N Mod 5);
  24.     End;
  25.   Form1.Memo1.Lines.Append(' L='+Copy(L,6,10)+Copy(L,1,5));
  26.   Result:=Copy(Result,6,10)+Copy(Result,1,5);
  27. End;
  28. // пользует ещё эту
  29. Function Von(C:Char;K:Byte):Byte;
  30. Var
  31.   N:Byte;
  32. Begin
  33.   If C In ['0'..'9'] Then Result:=Ord(C)-$30
  34.       Else
  35.     Begin
  36.       For N:=1 To 10 Do
  37.         If Symb[N]=C Then Break;
  38.       If N=11 Then Result:=K Mod 5
  39.               Else Result:=N-1;
  40.     End;
  41. End;


Как её обратить? Спать не могу!
PS: '& #036' = $

-----
z+Dw7uLu5+jqLCDq7vLu8PvpIPHs7uMh




Ранг: 52.1 (постоянный), 1thx
Активность: 0.020
Статус: Участник

Создано: 19 февраля 2009 12:16 · Поправил: Wyfinger
· Личное сообщение · #2

Я ошибаюсь, или первые два символа результата всегда '12' ?
add:
Понял, это не так.




Ранг: 527.7 (!), 381thx
Активность: 0.160.09
Статус: Участник
Победитель турнира 2010

Создано: 19 февраля 2009 13:41 · Поправил: OKOB
· Личное сообщение · #3

L всегда '0123401234' ??

Какой набор символов на входе?
S это 'Name', а Result это 'Serial'? Или наоборот?

Судя по Symb='ABEHKNRWXZ' набор ['0'..'9','A'..'Z'], а S это 'Name'.

-----
127.0.0.1, sweet 127.0.0.1




Ранг: 52.1 (постоянный), 1thx
Активность: 0.020
Статус: Участник

Создано: 19 февраля 2009 14:15
· Личное сообщение · #4

Возможно я маленько напутал с этой перестановкой в конце, и еще обращая функцию Van возможны варианты: можно выбрать результат из 0-9, ABEHKNRWXZ, либо найти печатный символ подходящий по модулю 5, поэтому мой вариант неполон, но вроде работает:
Code:
  1. // Восстанавливает символ из ABEHKNRWXZ или 0-9
  2. function unVon(V, N: Byte): Char;
  3. begin
  4.  if V = (N mod 5) then Result := Chr(N+$30) else
  5.    Result := Symb[(V+1) mod 10]; // Всегда 0..9
  6. end;
  7. // Восстановление последних символов
  8. function unFin(V, N: Byte): Char;
  9. begin
  10.  if V in [0..1] then Result := Symb[V+1] else
  11.    Result := Chr(N+$30);
  12. end;
  13. function unCode(inp: String): String;
  14. var
  15.   otp : string;
  16.   n,:Integer;
  17. begin
  18.  // Перевернем, я сделал, чтобы верно работало и для паролей короче 15 символов
  19.  inp := Copy(inp, length(inp)-4, 5) + Copy(inp, 1, length(inp)-5);
  20.  // Нужно восстановить первые 2 символа
  21.  for n := 1 to 2 do
  22.    otp := otp + unVon(Ord(inp[n])-$30, n);
  23.  // Восстанавливаем дальше
  24.  for m := n to Length(inp) do
  25.    if Von( inp[m-2] , m) + Von( inp[m-1] , m) <= 6 then
  26.      otp := otp + unVon(Ord(inp[m])-$30, m)
  27.    else
  28.      otp := otp + unFin(Ord(inp[m])-$30, m);
  29.  Result := otp;
  30. end;





Ранг: 756.3 (! !), 113thx
Активность: 0.610.05
Статус: Участник
Student

Создано: 19 февраля 2009 15:56 · Поправил: Isaev
· Личное сообщение · #5

OKOB пишет:
L всегда '0123401234' ??

Да, только '123401234012340'
OKOB пишет:
Какой набор символов на входе?

На входе строка типа 'R3B6ANW4X93ZKEH' всегда 15 символов из набора Symb+цифры
(т.е. из 'R3B6ANW4X93ZKEH' получием '574493242362140')
На выходе строка 15 символов, из только цифр... (0..9)
В обратной функции нужно с точностью до наоборот

Wyfinger сейчас проверим
Частично совпадает, но где-то косячок... Пробую найти

-----
z+Dw7uLu5+jqLCDq7vLu8PvpIPHs7uMh




Ранг: 52.1 (постоянный), 1thx
Активность: 0.020
Статус: Участник

Создано: 19 февраля 2009 16:05
· Личное сообщение · #6

Да, где-то у меня неточность, но на более коротких паролях все верно, в общем принцип вроде верен, дальше сами попробуйте..




Ранг: 527.7 (!), 381thx
Активность: 0.160.09
Статус: Участник
Победитель турнира 2010

Создано: 19 февраля 2009 18:11
· Личное сообщение · #7

Проблема обратимости в том, что функция Function Von(C:Char;K:Byte):Byte;
возвращает значения в диапазоне 0..9, причем одно и тоже значение для разных входных (неоднозначность)
Например: вернет 0 для
С = '0' (C in ['0'..'9'] then Result:=Ord(C)-$30)
или
С = 'A' (for N:=1 to 10 do if Symb[N]=C then break; (N=1) If N=11 Then Result:=K Mod 5 Else Result:=N-1;)
или
С = 'C' и K=5 (for N:=1 to 10 do if Symb[N]=C then break; (N=11) If N=11 Then Result:=K Mod 5 Else Result:=N-1;)

Поэтому при обращении и входном 0, неизвестно, что должно быть.

-----
127.0.0.1, sweet 127.0.0.1





Ранг: 756.3 (! !), 113thx
Активность: 0.610.05
Статус: Участник
Student

Создано: 19 февраля 2009 20:10 · Поправил: Isaev
· Личное сообщение · #8

OKOB пишет:
Поэтому при обращении и входном 0, неизвестно, что должно быть.

Там зависимость от впередистоящих символов
поэтому и считается
M:=Von(Result[N-2],N)+Von(Result[N-1],N);
и результат на выходе однозначный... т.е. в отладчике смотрю и в голове автоматически строю уже правильный код, а написать не могу Это уже диагноз

поэтому и обращать нужно учитывая предыдущие символы (или при обращении последующие) смотря откуда обходить
причём люди это дело закейгенили! (не учли только возможность русских имён) т.ч. всё должно быть однозначно

-----
z+Dw7uLu5+jqLCDq7vLu8PvpIPHs7uMh




Ранг: 52.1 (постоянный), 1thx
Активность: 0.020
Статус: Участник

Создано: 20 февраля 2009 02:36
· Личное сообщение · #9

Isaev пишет:
Там зависимость от впередистоящих символов

Да нет, конечно возможны неоднозначности.
Вот мой усовершенствованный вариант, работает отлично:
Code:
  1. // Получение случайного символа из диапазона
  2. function getRnd(V: string): Char;
  3. begin
  4.  Result := V[Random(Length(V))+1];
  5. end;
  6. // Восстанавливает символ из ABEHKNRWXZ или 0-9
  7. function unVon(V, N: Byte): Char;
  8. begin
  9.  if V = (N mod 5) then Result := getRnd('0123456789') else
  10.    Result := Symb[(V+1) mod 10];
  11. end;
  12. // Восстановление последних символов
  13. function unFin(V, N: Byte): Char;
  14. begin
  15.  if V = (N mod 5) then Result := getRnd('EHKNRWXZ')
  16.    else if V in [0..1] then Result := Symb[V+1]
  17.      else Result := Chr(+ $30);
  18. end;
  19. function unCode(inp: String): String;
  20. var
  21.   otp : string;
  22.   n,:Integer;
  23. begin
  24.  // Перевернем, я сделал, чтобы верно работало и для паролей короче 15 символов
  25.  inp := Copy(inp, length(inp)-4, 5) + Copy(inp, 1, length(inp)-5);
  26.  // Нужно восстановить первые 2 символа
  27.  for n := 1 to 2 do
  28.    otp := otp + unVon(Ord(inp[n])-$30, n);
  29.  // Восстанавливаем дальше
  30.  for m := n to Length(inp) do
  31.    begin
  32.      n :=  Von( inp[m-2] , m) + Von( inp[m-1] , m);
  33.      if n > 6 then
  34.        otp := otp + unFin(Ord(inp[m])-$30, m)
  35.      else
  36.        otp := otp + unVon(Ord(inp[m])-$30, m);
  37.    end;
  38.  Result := otp;
  39. end;
  40. //
  41. // Где-нибудь еще вызовите Randomize;
  42. //





Ранг: 756.3 (! !), 113thx
Активность: 0.610.05
Статус: Участник
Student

Создано: 20 февраля 2009 18:20 · Поправил: Isaev
· Личное сообщение · #10

Wyfinger Огромное спасибо!
Действительное работает при любых значениях! т.к. OKOB был прав, извиняюсь...
Я уж думал исходную функцию не правильно написал
один косяк только был
function unVon(V, N: Byte): Char;
begin
if V = (N mod 5) then Result := getRnd('0123456789') else
Result := Symb[V mod 10+1];
end;

-----
z+Dw7uLu5+jqLCDq7vLu8PvpIPHs7uMh




Ранг: 516.1 (!), 39thx
Активность: 0.280
Статус: Участник

Создано: 21 февраля 2009 13:14
· Личное сообщение · #11

Isaev, что за прога то?




Ранг: 756.3 (! !), 113thx
Активность: 0.610.05
Статус: Участник
Student

Создано: 21 февраля 2009 16:16
· Личное сообщение · #12

GuitarPro

-----
z+Dw7uLu5+jqLCDq7vLu8PvpIPHs7uMh



 eXeL@B —› Программирование —› FunctionReverse
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати