Python中等价于C#的GetBytes()方法是什么?

3 投票
2 回答
9590 浏览
提问于 2025-04-16 01:37

我有一个

byte[] request = UTF8Encoding.UTF8.GetBytes(requestParams); 

在一个C#的AES加密类里,我正在把它转换成Python。有没有人能告诉我在Python 2.5中怎么做(我在谷歌应用引擎上使用这个)?

示例输入:

请求参数: &r=p&playerid=6263017(或者其他查询字符串的组合)
开发者密钥: GK1FzK12iPYKE9Kt
开发者初始化向量: E2I21NEwsC9RdSN2
开发者ID: 12

Python函数:

def Encrypt(self, request_params, dev_key, dev_iv, dev_id):

    data_bytes = request_params.encode("utf-8")
    block_size = 16
    mode = AES.MODE_CBC
    assert len(dev_key) == block_size and len(dev_iv) == block_size

    pad_char = '0'
    pad_length = block_size - len(data_bytes) % block_size
    padded_data_bytes = data_bytes + pad_length * pad_char

    encrypted_bytes = dev_iv + AES.new(dev_key, mode, dev_iv).encrypt(padded_data_bytes)
    base64_encrypted_string = base64.urlsafe_b64encode(str(encrypted_bytes))
    request_uri = "http://api.blackoutrugby.com/?d=" + dev_id + "&er=" + base64_encrypted_string
    #http://api.blackoutrugby.com/?d=19&er=RTJJNTFORXdzQzNSZFNObNerdsGhiNoeue6c3mzed4Ty1YE-gTlVJVXHz05uPT-8
    # output from this Python code, it's incorrect
    #http://api.blackoutrugby.com/?d=19&er=16t2waGI2h657pzebN53hPr4kEjOzgsOEZiycDwPXR4=
    # correct output from C# code
    return request_uri

C#类:

using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;
using System.Net;
using System.Xml;
using Newtonsoft.Json;


namespace BlackoutRugbyPOC.Controllers {
    public class BlackoutRugbyAPI {
        public static string Request(string requestParams, string devKey, string devIV, string devID) {
            // Create an unencrypted request as an array of bytes
            byte[] request = UTF8Encoding.UTF8.GetBytes(requestParams);
            byte[] key = UTF8Encoding.UTF8.GetBytes(devKey);
            byte[] iv = UTF8Encoding.UTF8.GetBytes(devIV);

            AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
            aes.Key = key;
            aes.IV = iv;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.Zeros;

            // Get the transformer from the AES Encryptor
            ICryptoTransform cTransform = aes.CreateEncryptor();

            // Use the transformer to encrypt our request
            byte[] result = cTransform.TransformFinalBlock(request, 0, request.Length);
            aes.Clear();

            // Encode to base64
            string encryptedRequest = Convert.ToBase64String(result, 0, result.Length);

            // Send request to API
            string requestUri = "http://api.blackoutrugby.com/?d=" + devID + "&er=" + encryptedRequest;
            string xmlResponse = getWebResponse(requestUri);
            return XmlToJson(xmlResponse);
        }

        private static string getWebResponse(string url) {
            string html = "";

            WebRequest request = HttpWebRequest.Create(url);
            WebResponse response = request.GetResponse();

            using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
                html = reader.ReadToEnd();
            }
            return html;
        }

        public static string XmlToJson(string xml) {
            if (string.IsNullOrEmpty(xml))
                throw new ArgumentNullException("XML Input");

            XmlDocument doc = new XmlDocument();
            try {
                doc.LoadXml(xml);
            } catch {
                throw new ArgumentNullException("Input could not be loaded into XML Document");
            }

            return JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented);
        }
    }
}

谢谢,
Denis

2 个回答

-1

在编程中,有时候我们需要处理一些数据,这些数据可能来自不同的地方,比如用户输入、文件或者网络请求。为了让程序能够理解这些数据,我们通常需要将它们转换成一种程序能处理的格式。

比如说,如果我们从一个网页上获取了一些信息,可能这些信息是以文本的形式存在的。为了让程序能够使用这些信息,我们需要把它们转化为程序能理解的对象,比如数字、字符串或者其他类型的数据。

这个过程就叫做“数据解析”。解析的意思就是把复杂的东西拆解开来,变得简单易懂。就像我们在看一本书时,可能会遇到一些难懂的词汇,我们需要查字典来理解它们的意思。

在编程中,解析数据的方式有很多种,具体取决于数据的来源和格式。比如,如果数据是以JSON格式存储的,我们就可以使用一些特定的工具或者函数来解析它,把它转换成我们需要的格式。

总之,数据解析是编程中一个非常重要的步骤,它帮助我们把外部的数据转化为程序可以使用的形式,让我们的程序能够更好地工作。

     buffer = file.read(bytes)
2

不知道你从哪里得到以下代码

data_bytes = str.encode(request_params)
key_bytes = str.encode(dev_key)
iv_bytes = str.encode(dev_iv)

但你应该知道它和下面的代码是一样的:

data_bytes = request_params.encode("ascii")
key_bytes = dev_key.encode("ascii")
iv_bytes = dev_iv.encode("ascii")

这意味着如果这三个变量中有非ASCII字符,就会出错(希望你不会只用ASCII字符来生成AES密钥吧?)。

在Python 2.x中,str对象(在C#中是byte[])是字节,而unicode对象(在C#中是string)是用来表示文本的。顺便说一下,这个令人困惑的情况在Python 3.x中发生了变化。
这意味着如果request_params是一个Unicode对象,你应该把它编码成UTF-8;如果它是一个str对象,你应该假设(或者检查)它已经是UTF-8编码了。所以可能会像这样:

if isinstance(request_params, unicode):
    data_bytes = request_params.encode("utf-8")
else:
    request_params.decode("utf-8") # optional check whether it is correct UTF-8
    data_bytes = request_params

至于密钥和初始化向量(IV),它们总是二进制数据(例如,AES-128需要16个字节),而不是文本。所以它们没有字符编码。把那两行代码删掉,可能可以替换成:

assert len(dev_key) == block_size and len(dev_iv) == block_size

撰写回答