C#转换为Python(Linux)

2024-10-02 20:42:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有下面的代码(某种编码器,通过用置换等将一些字母表替换成另一个字母表来“编码”字符串)

using System;
using System.Text;
using System.Linq;

public class SorguDecrypt
{
    private char[] outAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/++".ToCharArray();

    private char[] inAlphabet = null;

    private Encoding turkishEncoding = null;

    public SorguDecrypt()
    {
        turkishEncoding = Encoding.GetEncoding("iso-8859-9");
        var bytes = Enumerable.Range(0, 255).Select(a => (byte)a).ToArray();
        inAlphabet = turkishEncoding.GetChars(bytes);
    }

    public string Decode(string cipherText)
    {
        if (String.IsNullOrEmpty(cipherText)) return String.Empty;

        StringBuilder decodedString = new StringBuilder();

        cipherText = cipherText.PadRight(((cipherText.Length - 1) / 4 + 1) * 4, (char)0);

        for (int j = 0; j < cipherText.Length; j += 4)
        {
            string s = cipherText.Substring(j, 4);

            int c1 = Array.IndexOf(outAlphabet,(s[0]));
            int c2 = Array.IndexOf(outAlphabet, (s[1])) + (s[0] == '/' ? 64 : 0) ;
            int c3 = Array.IndexOf(outAlphabet, (s[2])) + (s[1] == '/' ? 64 : 0) ;
            int c4 = Array.IndexOf(outAlphabet, (s[3])) + (s[2] == '/' ? 64 : 0) ;

            int r1 = (c2 * 16) / 255;
            int r2 = (c3 * 64) / 255;

            char dc1 = inAlphabet[(c1 * 4 + r1)];
            char dc2 = inAlphabet[((c2 * 16 + r2) % 256)];
            int r3 = Math.Min(254,(c3 - Array.IndexOf(inAlphabet, dc2) % 16 * 4) % 64 * 64 + c4);
            char dc3 = c4 != -1 ? inAlphabet[r3] : (char)0;

            decodedString.Append((dc1));
            if (c3 != -1) decodedString.Append((dc2));
            if (c4 != -1) decodedString.Append((dc3));
        }

        return decodedString.ToString();
    }

    public static void Main()
    {
        SorguDecrypt decrypter = new SorguDecrypt();
        string enc = "MLLBGL99845PGLfCII13GKH4HLFT";
        string dec = decrypter.Decode(enc);
        Console.WriteLine("{0}",dec);
    }

}

我想把它移植到Python(最好是原生的,不要使用Python)。到目前为止我所做的:

import array

outAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/++"
outAlphabet = list(outAlphabet.encode())
bytesIso8859_9 = array.array('B', [0xA4])
inAlphabet = bytesIso8859_9.tostring().decode("ISO-8859-9")

def Decode(cipherText):

    decodedString = ""
    cipherText = cipherText.ljust(((len(cipherText) - 1) / 4 + 1) * 4, '0')

    num1 = 0
    num2 = 4
    while num1 < len(cipherText):
        s = cipherText[num1:num2]

        c1 = outAlphabet.index(s[0])
        c2 = outAlphabet.index(s[1]) + int(('64' if s[0] == '/' else '0'))
        c3 = outAlphabet.index(s[2]) + int(('64' if s[1] == '/' else '0'))
        c4 = outAlphabet.index(s[3]) + int(('64' if s[2] == '/' else '0'))

        r1 = (c2 * 16) / 255
        r2 = (c3 * 64) / 255

        dc1 = inAlphabet[(c1 * 4 + r1)]
        dc2 = inAlphabet[((c2 * 16 + r2) % 256)]
        r3 = min(254,(c3 - inAlphabet.index(dc2) % 16 * 4) % 64 * 64 + c4)
        dc3 = (inAlphabet[r3] if c4 != -1 else '0')

        decodedString+=dc1
        if (c3 != -1):
            decodedString+=dc2
        if (c4 != -1):
            decodedString+=dc3

        num1 = num1 + 4
        num2 = num2 + 4

    return str(decodedString)

enc = "MLLBGL99845PGLfCII13GKH4HLFT"
dec = Decode(enc)
print(dec)

在C#下运行:

dec.exe
YUKARI AYAZLI CADDESİ

在Python下,我被卡住了:

$ python dec.py
Traceback (most recent call last):
  File "dec.py", line 44, in <module>
    dec = Decode(enc)
  File "dec.py", line 27, in Decode
    dc1 = inAlphabet[(c1 * 4 + r1)]
IndexError: string index out of range

我的第一个攻击是使用pythonnet,但我还有另一个问题:

import clr
from System import Text

outAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/++"
outAlphabet = list(outAlphabet.encode())
turkishEncoding = Text.Encoding.GetEncoding("iso-8859-9")
bytes = [bytes(a) for a in range(255)]
inAlphabet = turkishEncoding.GetChars(bytes)

def Decode(cipherText):
    decodedString = ""
    cipherText = cipherText.ljust(((len(cipherText) - 1) / 4 + 1) * 4, '0')

    num1 = 0
    num2 = 4
    while num1 < len(cipherText):
        s = cipherText[num1:num2]

        c1 = outAlphabet.index(s[0])
        c2 = outAlphabet.index(s[1]) + int(('64' if s[0] == '/' else '0'))
        c3 = outAlphabet.index(s[2]) + int(('64' if s[1] == '/' else '0'))
        c4 = outAlphabet.index(s[3]) + int(('64' if s[2] == '/' else '0'))

        r1 = (c2 * 16) / 255
        r2 = (c3 * 64) / 255

        dc1 = inAlphabet[(c1 * 4 + r1)]
        dc2 = inAlphabet[((c2 * 16 + r2) % 256)]
        r3 = min(254,(c3 - inAlphabet.index(dc2) % 16 * 4) % 64 * 64 + c4)
        dc3 = (inAlphabet[r3] if c4 != -1 else '0')

        decodedString+=dc1
        if (c3 != -1):
            decodedString+=dc2
        if (c4 != -1):
            decodedString+=dc3

        num1 = num1 + 4
        num2 = num2 + 4

    return str(decodedString)

enc = "MLLBGL99845PGLfCII13GKH4HLFT"
dec = Decode(enc)
print(dec)

也许我没有正确解析“iso-8859-9”字母表:

c:\Python27\python.exe dec.py
Traceback (most recent call last):
  File "dec.py", line 8, in <module>
    inAlphabet = turkishEncoding.GetChars(bytes)
TypeError: No method matches given arguments for GetChars

Tags: indexifdecintdecodec2c3ciphertext
3条回答

解决了将“ISO-8859-9”字符映射设置为字典的问题,如果有人知道其他更干净的方法,请告诉我:

#!/usr/bin/env python
# -*- coding: iso-8859-9 -*-

import array

outAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/++"
outAlphabet = list(outAlphabet.encode())
inAlphabet = {
  '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' : '', '32' : ' ', '33' : '!', '34' : '"',
  '35' : '#', '36' : '$', '37' : '%', '38' : '&', '39' : "'", '40' : '(', '41' : ')',
  '42' : '*', '43' : '+', '44' : ',', '45' : '-', '46' : '.', '47' : '/', '48' : '0',
  '49' : '1', '50' : '2', '51' : '3', '52' : '4', '53' : '5', '54' : '6', '55' : '7',
  '56' : '8', '57' : '9', '58' : ':', '59' : ';', '60' : '<', '61' : '=', '62' : '>',
  '63' : '?', '64' : '@', '65' : 'A', '66' : 'B', '67' : 'C', '68' : 'D', '69' : 'E',
  '70' : 'F', '71' : 'G', '72' : 'H', '73' : 'I', '74' : 'J', '75' : 'K', '76' : 'L',
  '77' : 'M', '78' : 'N', '79' : 'O', '80' : 'P', '81' : 'Q', '82' : 'R', '83' : 'S',
  '84' : 'T', '85' : 'U', '86' : 'V', '87' : 'W', '88' : 'X', '89' : 'Y', '90' : 'Z',
  '91' : '[', '92' : '\\', '93' : ']', '94' : '^', '95' : '_', '96' : '`', '97' : 'a',
  '98' : 'b', '99' : 'c', '100' : 'd', '101' : 'e', '102' : 'f', '103' : 'g', '104' : 'h',
  '105' : 'i', '106' : 'j', '107' : 'k', '108' : 'l', '109' : 'm', '110' : 'n', '111' : 'o',
  '112' : 'p', '113' : 'q', '114' : 'r', '115' : 's', '116' : 't', '117' : 'u', '118' : 'v',
  '119' : 'w', '120' : 'x', '121' : 'y', '122' : 'z', '123' : '{', '124' : '|', '125' : '}',
  '126' : '~', '127' : '', '128' : '', '129' : '', '130' : '', '131' : '', '132' : '',
  '133' : '', '134' : '', '135' : '', '136' : '', '137' : '', '138' : '', '139' : '',
  '140' : '', '141' : '', '142' : '', '143' : '', '144' : '', '145' : '', '146' : '',
  '147' : '', '148' : '', '149' : '', '150' : '', '151' : '', '152' : '', '153' : '',
  '154' : '', '155' : '', '156' : '', '157' : '', '158' : '', '159' : '', '160' : '',
  '161' : '¡', '162' : '¢', '163' : '£', '164' : '¤', '165' : '¥', '166' : '¦', '167' : '§',
  '168' : '¨', '169' : '©', '170' : 'ª', '171' : '«', '172' : '¬', '173' : '­', '174' : '®',
  '175' : '¯', '176' : '°', '177' : '±', '178' : '²', '179' : '³', '180' : '´', '181' : 'µ',
  '182' : '¶', '183' : '·', '184' : '¸', '185' : '¹', '186' : 'º', '187' : '»', '188' : '¼',
  '189' : '½', '190' : '¾', '191' : '¿', '192' : 'À', '193' : 'Á', '194' : 'Â', '195' : 'Ã',
  '196' : 'Ä', '197' : 'Å', '198' : 'Æ', '199' : 'Ç', '200' : 'È', '201' : 'É', '202' : 'Ê',
  '203' : 'Ë', '204' : 'Ì', '205' : 'Í', '206' : 'Î', '207' : 'Ï', '208' : 'Ğ', '209' : 'Ñ',
  '210' : 'Ò', '211' : 'Ó', '212' : 'Ô', '213' : 'Õ', '214' : 'Ö', '215' : '×', '216' : 'Ø',
  '217' : 'Ù', '218' : 'Ú', '219' : 'Û', '220' : 'Ü', '221' : 'İ', '222' : 'Ş', '223' : 'ß',
  '224' : 'à', '225' : 'á', '226' : 'â', '227' : 'ã', '228' : 'ä', '229' : 'å', '230' : 'æ',
  '231' : 'ç', '232' : 'è', '233' : 'é', '234' : 'ê', '235' : 'ë', '236' : 'ì', '237' : 'í',
  '238' : 'î', '239' : 'ï', '240' : 'ğ', '241' : 'ñ', '242' : 'ò', '243' : 'ó', '244' : 'ô',
  '245' : 'õ', '246' : 'ö', '247' : '÷', '248' : 'ø', '249' : 'ù', '250' : 'ú', '251' : 'û',
  '252' : 'ü', '253' : 'ı', '254' : 'ş'
}

def Decode(cipherText):

    decodedString = ""
    cipherText = cipherText.ljust(((len(cipherText) - 1) / 4 + 1) * 4, '0')

    num1 = 0
    num2 = 4
    while num1 < len(cipherText):
        s = cipherText[num1:num2]

        c1 = outAlphabet.index(s[0])
        c2 = outAlphabet.index(s[1]) + int(('64' if s[0] == '/' else '0'))
        c3 = outAlphabet.index(s[2]) + int(('64' if s[1] == '/' else '0'))
        c4 = outAlphabet.index(s[3]) + int(('64' if s[2] == '/' else '0'))

        r1 = (c2 * 16) // 255
        r2 = (c3 * 64) // 255

        dc1 = inAlphabet[str((c1 * 4 + r1))]
        dc2 = inAlphabet[str(((c2 * 16 + r2) % 256))]
        r3 = min(254,(c3 - ((c2 * 16 + r2) % 256) % 16 * 4) % 64 * 64 + c4)
        dc3 = (inAlphabet[str(r3)] if c4 != -1 else '0')

        decodedString+=dc1
        if (c3 != -1):
            decodedString+=dc2
        if (c4 != -1):
            decodedString+=dc3

        num1 = num1 + 4
        num2 = num2 + 4

    return str(decodedString)

enc = "MLLBGL99845PGLfCII13GKH4HLFT"
dec = Decode(enc)
print(dec)

输出:

$ python dec.py
YUKARI AYAZLI CADDESİ

如果您使用的是较低的python版本,如Python2.7,则不会造成问题,因为在这个版本中,它只为“/”操作返回整数

但在Python3.x中,它返回实数而不是整数

在Python 3.6中

   r1 = (143 * 16) / 255
   print(r1)

输出:8.972549019607843

在Python2.7中

   r1 = (143 * 16) / 255
   print(r1)

输出:8

我认为问题在于c#

int r1 = (c2 * 16) / 255;

返回一个int,但为python格式

r1 = (c2 * 16) / 255

可以返回不能用作索引的实数

相关问题 更多 >