Lock2Key

Описание:

Реализация в различных языках функции lock2key для нахождения ключа по параметру команды $Lock.

Язык С/C++:

char *lock2key(char *lock)
{
 int len = strlen(lock);
 char *key = (char *)calloc(1, len + 1);

 int i;
 for(i = 1; i < len; ++i)
key[i] = lock[i] ^ lock[i-1];
  key[0] = lock[0] ^ lock[len-1] ^ lock[len-2] ^ 5;

 for(i = 0; i < len; ++i)
key[i] = ((key[i]<<4) & 0xF0) | ((key[i]>>4) & 0x0F);

 char *newkey = (char *)calloc(1, len + 100);
 char *newkey_p = newkey;
 for(i = 0; i < len; ++i)
  {
switch(key[i])
{
 case 0:
 case 5:
 case 36:
 case 96:
 case 124:
 case 126:
sprintf(newkey_p, "/%%DCN%03d%%/", key[i]);
newkey_p += 10;
break;
 default:
*newkey_p = key[i];
++newkey_p;
}
  }
 *newkey_p = '\0';
 return newkey;
}

Язык C++:

/// DCN экранирование
void DCN_Escape(const char *sBuf, int iLen, string &sDest)
{
  sDest.clear();
 unsigned char c;
 char buf[11];
 while(iLen-- > 0) {
    c = *(sBuf++);
   switch(c) {
     case 0:
     case 5:
     case 36:
     case 96:
     case 124:
     case 126:
        sprintf(buf, "/%%DCN%03d%%/", c);
        sDest += buf;
       break;
     default:
        sDest += c;
       break;
    }
  }
}

/// DCN разэкранирование
void DCN_UnEscape(const string &sSrc, char *sDest, int &iLen)
{
  string sStart = "/%DCN", sEnd = "%/";
 unsigned char c;
  size_t iPos = sSrc.find(sStart), iPos2 = 0;
  iLen = 0;
 while((iPos != sSrc.npos) && (iLen < sSrc.size())) {
   if(iPos > iPos2) {
      memcpy(sDest + iLen, sSrc.c_str() + iPos2, iPos - iPos2);
      iLen += iPos - iPos2;
    }
    iPos2 = sSrc.find(sEnd, iPos);
   if((iPos2 != sSrc.npos) &&
      (iPos2 - iPos <= sStart.size() + 3)) {
        c = atoi(sSrc.substr(iPos + sStart.size(), 3).c_str());
        sDest[iLen++] = c;
        iPos2 += sEnd.size();
    }
    iPos = sSrc.find(sStart, iPos + 1);
  }
 if (iPos2 < sSrc.size()) {
    memcpy(sDest + iLen, sSrc.c_str() + iPos2, sSrc.size() - iPos2 + 1);
    iLen += sSrc.size() - iPos2;
  }
}

/// Функция кодирования
void lock2key(const string &sLock, string &sKey)
{
 int iCount = 0, iLen = sLock.size();
 char *key = 0, *lock = new char[iLen + 1];
  DCN_UnEscape(sLock, lock, iLen);
 
  key = new char[iLen + 1];
 
  key[0] = lock[0] ^ lock[iLen - 1] ^ lock[iLen - 2] ^ 5;
 while(++iCount < iLen) key[iCount] = lock[iCount] ^ lock[iCount - 1];
  key[iLen] = 0;
 
  iCount = -1;
 while(++iCount < iLen) key[iCount] = ((key[iCount] << 4)) | ((key[iCount] >> 4));
 
  DCN_Escape(key, iLen, sKey);
 delete [] key;
 delete [] lock;
}

Язык C#:

private static string lock2key(string Lock)
{
 int i, len = Lock.Length;
 byte[] key = new byte[len];
 for(i = 1; i < len; ++i)
    key[i] = (byte)(Lock[i] ^ Lock[i - 1]);
  key[0] = (byte)(Lock[0] ^ Lock[len - 1] ^ Lock[len - 2] ^ 5);

 for(i = 0; i < len; ++i)
    key[i] = (byte)(((key[i] << 4) & 0xF0) | ((key[i] >> 4) & 0x0F));

 string Buf = "", Key = Encoding.Default.GetString(key);
 for(i = 0; i < len; ++i)
 switch((int)Key[i]) {
   case 0:
   case 5:
   case 36:
   case 96:
   case 124:
   case 126:
      Buf += String.Format("/%DCN{0:000}%/", (int)Key[i]);
     break;
   default:
      Buf += Key[i];
     break;
  }
 return Buf;
}

Язык Lua (5.1):

function lock2key(lock)
 local function bitwise(x, y, bw)
local c, p = 0, 1
local function bODD(x)
 return x ~= math.floor(x / 2) * 2
end
while x > 0 or y > 0 do
 if bw == "xor" then
if (bODD(x) and not bODD(y)) or
(bODD(y) and not bODD(x)) then
 c = c + p
end
 elseif bw == "and" then
if bODD(x) and bODD(y) then
 c = c + p
end
 elseif bw == "or" then
if bODD(x) or bODD(y) then
 c = c + p
end
 end
 x = math.floor(x / 2)
 y = math.floor(y / 2)
 p = p * 2
end
return c
 end

 local key = {}
 table.insert(key,
    bitwise(bitwise(bitwise(string.byte(lock, 1),
         string.byte(lock, -1),
         "xor"),
       string.byte(lock, -2),
       "xor"),
     5,
     "xor"))
 for i=2, string.len(lock),1 do
table.insert(key, bitwise(string.byte(lock, i), string.byte(lock, i - 1), "xor"))
 end

 local function nibbleswap(bits)
return bitwise(bitwise(bits * (2 ^ 4), 240, "and"),
bitwise(math.floor(bits / (2 ^ 4)), 15, "and"), "or")
 end

 local g = {["5"] = 1, ["0"] = 1, ["36"] = 1, ["96"] = 1, ["124"] = 1, ["126"] = 1}
 for i=1, #key do
local b = nibbleswap(rawget(key, i))
rawset(key, i, (g[tostring(b)] and
string.format("/%%DCN%03d%%/", b) or string.char(b)))
 end

 return table.concat(key)
end

Язык PHP:

function lock2key($_LOCK, $port) {
  $lockLength = strlen($_LOCK);
  $LockToKey = '';

  for ($j = 0; $j < strlen($_LOCK); $j++) {
    if($j == 0) {
      $h = ord($_LOCK{0}) ^ ord( $_LOCK{ $lockLength - 1} ) ^ ord( $_LOCK{ $lockLength - 2} ) ^ 5;
    } else {
      $h = ord($_LOCK{$j}) ^ ord($_LOCK{$j-1});
    }

    $h = $h % 256;
    $a = (($h<<4) & 240) | (($h>>4) & 15);

    if($a == '126' or $a == '124' or $a == '96' or $a == '36' or $a == '5' or $a == '0') {
      $LockToKey .= "/%DCN";

      if ($a < 100) $LockToKey .= "0";
      if ($a < 10) $LockToKey .= "0";

      $LockToKey .= $a;
      $LockToKey .= "%/";
    } else {
      $LockToKey .= chr($a);
    }
  }
  return $LockToKey;
}

Язык Perl:

sub lock2key($)
{
 my @lock = split(//, shift);
 my $i;
 my @key = ();
 # convert to ordinal
 map {$_=ord} @lock;
 # calc key[0] with some xor-ing magic
 push(@key,$lock[0]^5);
 # calc rest of key with some other xor-ing magic
 for ($i=1;$i<@lock;$i++)
  {
push(@key, ($lock[$i]^$lock[$i-1]));
  }
 # nibble swapping
 for ($i=0;$i<@key;$i++)
  {
$key[$i] = ((($key[$i] << 4) & 240) | (($key[$i] >> 4) & 15)) & 0xff;
  }
 $key[0] = $key[0] ^ $key[ @key - 1 ];
 # escape some
 foreach (@key)
  {
$_ = ( $_ == 0 || $_ == 5 || $_ == 36 ||
$_ == 96 || $_ == 124 || $_ ==
126 ) ? sprintf('/%%DCN%03i%%/', $_) : chr;
  }
 # done
 return join('', @key);
}

Язык Delphi / Pascal:

function lock2key(StrLock : string) : string;

 // The follow function converts "1" (byte) to "001" (string), "10" to "010" and so on
 function ByteToThreeCharStr (Value : byte) : string;
 begin
if value < 10 then
 result := '00'+inttostr(value)
else
 if value < 100 then
result := '0'+inttostr(value)
 else
result := inttostr(value);
 end;

 var i : byte;
  Temp : string;
  TempChar : byte;

begin
 result := '';
 if length (StrLock) < 3 then
 begin
result := 'BROKENCLIENT';
setlength (result,length(strlock));
exit;
 end;

 // First char
  temp := chr (ord (StrLock[1]) xor ord (StrLock[length(StrLock)])
xor ord (StrLock[length(strLock)-1]) xor 5);

 for i := 2 to length (StrLock) do
temp := temp + chr (ord(StrLock[i]) xor ord (StrLock[i-1]));

 for i := 1 to length (temp) do
 begin
TempChar := ord (temp[i]);

// I now used assembler. In the visual basic code the same was done with ugly math
asm // <- Nibble swap! We swap the last four 
 // bits with the first four: 00101111 -> 11110010
 ror TempChar, 4
end;

// Some chars need to be replaced with a string like "/%DCN005%/"
If (TempChar = 0) or (TempChar = 5) or (TempChar = 36) or (TempChar = 96)
 or (TempChar = 124) or (TempChar = 126)
then
 result := result + '/%DCN' + ByteToThreeCharStr(TempChar) + '%/'
else
 result := result + chr (TempChar);
 end;
end;

Язык Java:

private static final String CHARENCODING = "windows-1252";

public static String generateKey(String lockstr) throws UnsupportedEncodingException {
 byte[] lock = lockstr.split(" ", 3)[1].getBytes(CHARENCODING);
 byte[] key =  new byte[lock.length];
 for (int i = 1; i < lock.length; i++) {
key[i] = (byte) ((lock[i] ^ lock[i - 1]) & 0xFF);
 }
  key[0] = (byte) ((((lock[0] ^ lock[lock.length - 1]) ^ lock[lock.length - 2]) ^ 5) & 0xFF);
 for (int i = 0; i < key.length; i++) {
key[i] = (byte) ((((key[i] << 4) & 0xF0) | ((key[i] >> 4) & 0x0F)) & 0xFF);
 }
  String modifiedLock = new String(key,CHARENCODING);
 return dcnEncode(modifiedLock);
}

private static String dcnEncode(String lockstring) {
 for (int i: new int[]{0,5,36,96,124,126}) {
String paddedDecimal = String.format("%03d", i);
String paddedHex = String.format("%02x", i);
lockstring = lockstring.replaceAll("\\x"+paddedHex, "/%DCN"+paddedDecimal+"%/");
 }
 return "$Key "+lockstring+"|";
}

Язык Visual Basic:

Public Function Lock2Key(StrLock As String) As String Dim TLock2Key As String, TChar As Integer If Len(StrLock) < 3 Then Lock2Key = Left$("BROKENCLIENT", Len(StrLock)) Exit Function End If TLock2Key = Chr$(Asc(Left$(StrLock, 1)) Xor Asc(Right$(StrLock, 1)) Xor Asc(Mid$(StrLock, Len(StrLock) - 1, 1)) Xor 5) For i = 2 To Len(StrLock) TLock2Key = TLock2Key & Chr$(Asc(Mid$(StrLock, i, 1)) Xor Asc(Mid$(StrLock, i - 1, 1))) Next i For i = 1 To Len(TLock2Key) TChar = Asc(Mid$(TLock2Key, i, 1)) TChar = TChar * 16 + TChar \ 16 'Swap bits 11110000 -> 00001111 TChar = TChar Mod 256 If TChar = 0 Or TChar = 5 Or TChar = 36 Or TChar = 96 Or TChar = 124 Or TChar = 126 Then Lock2Key = Lock2Key & "/%DCN" & Right$("000" & TChar, 3) & "%/" Else Lock2Key = Lock2Key & Chr$(TChar) End If Next i End Function Case "$LOCK" 'You've recived $LOCK, convert it to $KEY Dim sLock2 As String sLock2 = Split(Mid(sData2, 7), " Pk=")(0) sLock2 = Lock2Key(sLock2)

Язык Python:

lock = self.sock.recv(1024)
lock = re.findall('\$Lock[\s](.*?)[\s]', lock)[0]
  
key = {}
  
for i in xrange(1, len(lock)):
  key[i] = ord(lock[i]) ^ ord(lock[i-1])
  
key[0] = ord(lock[0]) ^ ord(lock[len(lock)-1]) ^ ord(lock[len(lock)-2]) ^ 5
for i in xrange(0, len(lock)):
  key[i] = ((key[i]<<4) & 240) | ((key[i]>>4) & 15)
  
out = ""
for i in xrange(0, len(lock)):
  out += unichr(key[i])
  
out = out.replace(u'\0', u'/%DCN000%/').replace(u'\5',
u'/%DCN005%/').replace(u'\44', u'/%DCN036%/')
out = out.replace(u'\140', u'/%DCN096%/').replace(u'\174',
u'/%DCN124%/').replace(u'\176', u'/%DCN126%/')

Язык Python 2.5.2 (Ubuntu 8.10):

# "lock" must be the exact lock character sequence, not the whole command.
# i.e. if the command is $Lock blah pk=bleh|, lock should be "blah"
def lock_to_key(lock):
 "Decrypts lock to key."
  key = {}
 for i in xrange(1, len(lock)):
key[i] = ord(lock[i]) ^ ord(lock[i-1])
  key[0] = ord(lock[0]) ^ ord(lock[len(lock)-1]) ^ ord(lock[len(lock)-2]) ^ 5
 for i in xrange(0, len(lock)):
key[i] = ((key[i]<<4) & 240) | ((key[i]>>4) & 15)
  out = ""
 for i in xrange(0, len(key)):
if key[i] in (0, 5, 36, 96, 124, 126):
 out += "/%%DCN%03d%%/" % (key[i],)
else:
 out += chr(key[i])
 return out

Оригинал (by Setuper): http://mydc.ru/index.html?showtopic=915&view=findpost&p=19477

Тэги:
Код для вставки: :: :: :: ГОСТ ::
Поделиться: //
 

Реклама

Для скачивания с этих сайтов нужно подключиться к внешним хабам

Нужен свой портал? magneto!