Files
2026-06-01 12:46:52 +02:00

206 lines
4.9 KiB
C++

#include "../../include/kfile/KFileNameCipher.h"
#include <assert.h>
#include <locale>
static const int MAGIC_DEPTH_NUMBER = 32;
static char encTable[] =
{
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'g', ' ', 0, '&', 'w', ',', 'l', 'N', 'X', 'O', 0, '7', '.', '%', 'e', 0, '8', '_', ']', '#', 'P', '1', '-', '$', 'V', '[', 0, 'Y', 0, '^', 0, 0,
'K', '}', 'j', '0', '@', 'G', 'S', ')', 'A', 'x', 'y', '6', '9', 'E', 'F', '{', 'W', 'b', '=', 'R', 'v', 't', 'h', '2', '4', 'M', '(', 'k', 0, 'm', 'a', '+',
'~', 'D', '\'', 'C', '!', 'J', 'I', 'd', 'B', 'U', '`', 'q', 'f', 'p', 'H', 'Q', '3', 'L', 'n', 'o', 'Z', 'i', 'r', 's', 'u', ';', 'z', 'c', 0, 'T', '5', 0,
};
static char decTable[] =
{
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'!', 'd', 0, '3', '7', '-', '#', 'b', 'Z', 'G', 0, '_', '%', '6', ',', 0, 'C', '5', 'W', 'p', 'X', '~', 'K', '+', '0', 'L', 0, 'y', 0, 'R', 0, 0,
'D', 'H', 'h', 'c', 'a', 'M', 'N', 'E', 'n', 'f', 'e', '@', 'q', 'Y', '\'', ')', '4', 'o', 'S', 'F', '}', 'i', '8', 'P', '(', ';', 't', '9', 0, '2', '=', '1',
'j', '^', 'Q', '{', 'g', '.', 'l', ' ', 'V', 'u', 'B', '[', '&', ']', 'r', 's', 'm', 'k', 'v', 'w', 'U', 'x', 'T', '$', 'I', 'J', 'z', 'O', 0, 'A', '`', 0,
};
static char refTable[] = "^&T_Nsd{xo5v`rOYV+,iIU#kCJq8$'~L0P]FeBn-Au(pXHZhwDy2}agWG7K=bQ;SRt)46l@jE%9!c1[3fmMz";
static char GetEncChar( char c, int depth )
{
assert( depth > 0 );
assert( c > 0 );
char ret = c;
for ( int i = 0; i < depth; ++i )
{
ret = encTable[ret];
}
return ret;
}
static char GetDecChar( char c, int depth )
{
assert( depth > 0 );
assert( c > 0 );
char ret = c;
for ( int i = 0; i < depth; ++i )
{
ret = decTable[ret];
}
return ret;
}
static int GetStartDepth( const std::string& strFileName )
{
int key = 0;
for ( size_t i = 0; i < strFileName.length(); ++i )
{
key += 17 * strFileName[i] + 1;
}
key += static_cast< int >( strFileName.length() );
int ret = key % MAGIC_DEPTH_NUMBER;
if ( ret == 0 )
{
ret = MAGIC_DEPTH_NUMBER;
}
return ret;
}
static char GetParityChar( const std::string & strEncName )
{
int key = 0;
for ( size_t i = 0; i < strEncName.length(); ++i )
{
key += strEncName[i];
}
key = key % strlen( refTable );
return refTable[ key ];
}
static void ReverseString( std::string & strString )
{
size_t len = strString.size();
std::swap( strString[0], strString[(int)(len*0.66f)] );
std::swap( strString[1], strString[(int)(len*0.33f)] );
}
namespace KFileNameCipher
{
bool IsEncodedName( const std::string & strFileName )
{
if ( strFileName.length() < 4 )
return false;
std::string strExt = strFileName.substr( strFileName.length() - 4, strFileName.length() );
if( _stricmp( strExt.c_str(), ".ogg" ) == 0 ) return false;
std::string strTest = strFileName.substr( 1, strFileName.length() - 2 );
ReverseString( strTest );
if ( strFileName[ 0 ] == GetParityChar( strTest ) )
return true;
return false;
}
void EncodeFileName( std::string & strFileName )
{
std::string strString = strFileName;
for ( size_t i = 0; i < strString.size(); ++i )
{
strString[i] = static_cast< char >( ::tolower( strString[i] ) );
}
if ( strString.empty() )
return;
size_t len = strString.length();
int start_depth;
int depth;
start_depth = depth = GetStartDepth( strString );
for ( size_t i = 0; i < len; ++i )
{
char c = strString[ i ];
strString[ i ] = GetEncChar( c, depth );
depth = (depth + c * 17 + 1) % MAGIC_DEPTH_NUMBER;
if ( depth == 0 )
{
depth = MAGIC_DEPTH_NUMBER;
}
}
std::string strResult;
strResult += GetParityChar( strString );
ReverseString( strString );
strResult += strString;
strResult += refTable[ start_depth ];
strFileName = strResult;
}
void DecodeFileName( std::string & strFileName )
{
std::string strString = strFileName;
if ( !IsEncodedName( strString ) )
return;
int depth = 0;
int refTableLen = static_cast< int >( strlen( refTable ) );
for ( int i = 0; i < refTableLen; ++i )
{
if ( refTable[i] == strString[strString.length() - 1] )
{
depth = i;
break;
}
}
if ( depth == 0 )
return;
strString = strString.substr( 1, strString.length() - 2 );
ReverseString( strString );
size_t len = strString.length();
for ( size_t i = 0; i < len; ++i )
{
strString[ i ] = GetDecChar( strString[ i ], depth );
depth = (depth + strString[ i ] * 17 + 1) % MAGIC_DEPTH_NUMBER;
if ( depth == 0 )
{
depth = MAGIC_DEPTH_NUMBER;
}
}
strFileName = strString;
}
};