cuốn sách gpt4 ai đã làm

C#:Blowfish mã hóa một từ kép

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 12:28:25 26 4
mua khóa gpt4 Nike

Tôi đang dịch ứng dụng khách C++ TCP sang C#. Ứng dụng khách này được sử dụng để mã hóa 4 byte của một mảng bằng cách sử dụng Blowfish.

Cá nóc C++

C# Blowfish (C# NET)

C++

    Phản hồi BYTE [6] = 
{
0x00, 0x80, 0x01, 0x61, 0xF8, 0x17
};

// Chỉ mã hóa 4 byte cuối cùng của gói (0x01,0x061,0xF8,0x17)
Blowfish.Encode(phản hồi + 2, phản hồi + 2, 4);

// Gửi gói tin
gửi(s, (char*)sendPtr, sendSize, 0);

C#

    phản hồi = byte mới [6] { 0x00, 0x80, 0x01, 0x61, 0xF8, 0x17};

// Chỉ mã hóa 4 byte cuối cùng của gói (0x01,0x061,0xF8,0x17)
Handshake.blowfish.Encrypt(phản hồi, 2, phản hồi, 2, 4);

// Gửi gói tin
WS.sock.Send(được mã hóa);

Trong mã C++, khi dòng "Blowfish.Encode" được gọi với các tham số này, nó sẽ nhập hàm cBlowfish.Encrypt

DWORD cBlowFish::Encode(BYTE * pInput, BYTE * pOutput, DWORD lSize)
{
DWORD lCount, lOutSize, lGoodBytes;
BYTE *pi, *po;
int tôi, j;
int SameDest =(pInput == pOutput ? 1 : 0);

lOutSize = GetOutputLength(lSize);
for(lCount = 0; lCount < lOutSize; lCount += 8)
{
if(SameDest) // nếu dữ liệu được mã hóa đang được ghi vào bộ đệm đầu vào
{
if(lCount < lSize - 7) // nếu không xử lý các byte không đồng đều ở cuối
{
Blowfish_encipher((DWORD *) pInput, (DWORD *)(pInput + 4));
}
else // đệm cuối dữ liệu bằng byte rỗng để hoàn tất mã hóa
{
po = pInput + lSize // trỏ vào byte sau cuối dữ liệu thực tế
j =(int)(lOutSize - lSize); // số byte được đặt thành null
for(i = 0; i < j; i++)
*po++ = 0;
Blowfish_encipher((DWORD *) pInput, (DWORD *)(pInput + 4));
}
pĐầu vào += 8;
}
else // bộ đệm đầu ra không bằng bộ đệm đầu vào nên phải sao chép
{ // đầu vào vào bộ đệm đầu ra trước khi mã hóa
if(lCount < lSize - 7) // nếu không xử lý các byte không đồng đều ở cuối
{
pi = pĐầu vào;
po = pĐầu ra;
cho(i = 0; i < 8; i++)
// sao chép byte vào đầu ra
*po++ = *pi++;
// bây giờ mã hóa chúng
Blowfish_encipher((DWORD *) pOutput, (DWORD *)(pOutput + 4));
}
else // đệm cuối dữ liệu bằng byte rỗng để hoàn tất mã hóa
{
lGoodBytes = lSize - lCount; // số byte dữ liệu còn lại
po = pĐầu ra;
for(i = 0; i <(int) lGoodBytes; i++)
*po++ = *pInput++;
for(j = i; j < 8; j++)
*po++ = 0;
Blowfish_encipher((DWORD *) pOutput, (DWORD *)(pOutput + 4));
}
pĐầu vào += 8;
pĐầu ra += 8;
}
}
trả về lOutSize;
}

Để rõ ràng, vòng lặp chỉ được thực hiện một lần vì độ dài của byte được truyền ngắn hơn (4).

Chỉ có một cuộc gọi được thực hiện (chỉ một lần) từ mã khổng lồ này và cuộc gọi là:

Blowfish_encipher((DWORD *) pInput, (DWORD *)(pInput + 4));

// Chỉ ra rằng mã vượt qua hai câu lệnh if đầu tiên rồi rời khỏi vòng lặp và hàm.

Theo quan điểm của tôi, giải pháp được ẩn giấu ở đâu đó trong chức năng mã hóa:

void cBlowFish::Blowfish_encipher(DWORD *xl, DWORD *xr)
{
công đoàn từ Xl, Xr;

Xl.dword = *xl;
Xr.dword = *xr;

Xl.dword ^= PArray [0];
VÒNG(Xr, Xl, 1);
VÒNG(Xl, Xr, 2);
VÒNG(Xr, Xl, 3);
VÒNG(Xl, Xr, 4);
VÒNG(Xr, Xl, 5);
VÒNG(Xl, Xr, 6);
VÒNG(Xr, Xl, 7);
VÒNG(Xl, Xr, 8);
VÒNG(Xr, Xl, 9);
VÒNG(Xl, Xr, 10);
VÒNG(Xr, Xl, 11);
VÒNG(Xl, Xr, 12);
VÒNG(Xr, Xl, 13);
VÒNG(Xl, Xr, 14);
VÒNG(Xr, Xl, 15);
VÒNG(Xl, Xr, 16);
Xr.dword ^= PArray [17];

*xr = Xl.dword;
*xl = Xr.dword;
}

定义:

#define S(x,i) (SBoxes[i][xwbyte##i])
#define bf_F(x) (((S(x,0) + S(x,1)) ^ S(x,2)) + S(x,3))
#define ROUND(a,b,n) (a.dword ^= bf_F(b) ^ PArray[n])

Vấn đề là hàm Blowfish_Encipher trong C++ có hai tham số: Đầu vào(xl) dưới dạng dword và Đầu ra(xr) dưới dạng dword.

Hàm Blowfish Encrypt_Block trong C# có bốn tham số.

        public void EncryptBlock(uint hi,uint lo,out uint outHi,out uint outLo)

Không giống như cá kiếm C++, EncryptBlock gọi Encrypt thay vì Encrypt gọi EncryptBlock. Có lẽ EncryptBlock không phải là C++ Blowfish_Encipher?

Dù sao, vấn đề của tôi là khi tôi gọi mã C++ của mình bằng một mảng 6 byte, tôi yêu cầu Blowfish chỉ mã hóa 4 byte cuối cùng, đúng như vậy.

Mặc dù nếu tôi gọi hàm mã hóa trong C# bằng 4 byte này, nó sẽ trả về 0x00. (Nếu bạn muốn xem C# Blowfish, hãy xem dòng đầu tiên của tôi - tôi đã thêm siêu liên kết vào đó).

Lưu ý rằng tôi không thể thay đổi cấu trúc gói tin, lẽ ra nó phải như vậy nhưng được mã hóa.

Tôi cũng đã thử điều này:

Biết rằng hàm Encrpypt của C++ chỉ thực hiện một lệnh gọi - Blowfish Encipher. Tôi đã thử gọi trực tiếp EncryptBlock bằng C# nhưng đầu vào và đầu ra có Hi Uint32 và Low Uint32, làm cách nào tôi có thể phân tán chúng thành HI hoặc LO? Điều này có hoạt động không nếu Encrypt_Block gọi Blowfish Encrypt trong C#? Tôi không chắc.

Cảm ơn trước!

câu trả lời hay nhất

Blowfish hoạt động trên các khối 8 byte. Cách duy nhất để mã hóa dữ liệu nhỏ hơn 8 byte (hoặc bội số của 8) là đệm dữ liệu đó (trong trường hợp này là số 0).

Bạn cần chuyển bộ đệm tám byte vào hàm C++ của mình vì bạn đang mã hóa tại chỗ. Mã bạn đã đăng thực sự sẽ mã hóa bốn byte bổ sung của bộ nhớ liền kề ((DWORD *)(pInput + 4)), đó rõ ràng không phải là điều bạn muốn. Hơn nữa, tất cả tám byte đầu ra đều cần thiết để giải mã - vì vậy, thật không may, bạn không thể chỉ chuyển bốn byte được mã hóa và mong đợi chúng được giải mã thành công ở đầu bên kia.

Tôi biết điều này không giải quyết được vấn đề của bạn - tôi không thấy cách nào khác, vì bạn chỉ muốn gửi bốn byte dữ liệu được mã hóa và Blowfish luôn tạo ra ít nhất tám byte!

Về C#:Blowfish mã hóa một từ kép, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/705596/

26 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress