Je suis en train de faire une routine de manipulation pour encoder/décoder des fichiers mp3. Cependant, je devrai les encoder en utilisant C#, et les décoder en utilisant Delphi XE 10. J'ai écrit le code qui les code/les décode, et ça marche quand il est exécuté sur la même plate-forme (si je code/décode en C# , et si je code/décode en Delphi les jeux mp3), mais si j'essaye de décoder un mp3 encodé en C#, le mp3 ne joue pas. En faisant ce processus seulement avec la chaîne, cela a fonctionné, donc c'est probablement quand j'ai essayé de l'appliquer au MemoryStream
. À la fin, j'ai édité le poste, et ajouté les fonctions que j'ai utilisé les chaînes encoder/décoder seulement, et je peux encoder avec succès en C#, et décoder en Delphi. J'ai changé la chaîne de hachage, mais il est similaire à celui utilisé dans les échantillonsCompatibilité sur la manipulation de bits entre C# et Delphi lors de la gestion de fichiers
Voici le code en C#:
private void btnCodificarArquivos_Click(object sender, EventArgs e)
{
Encoding ANSI = Encoding.GetEncoding(1252);
byte[] hash = ANSI.GetBytes(@"laki#~~2p3fijo3ij881*2f-|- a`asso`wpeofi#[email protected]");
string directory;
string originalExtension;
string finalExtension;
if (cbxCodificar.Checked)
{
originalExtension = "mp3";
finalExtension = "mpc";
}
else
{
originalExtension = "mpc";
finalExtension = "mp3";
}
directory = txbFrase.Text.Trim();
if (!Directory.Exists(directory))
throw new Exception("Directory does not exist => " + directory);
var files = Directory.GetFiles(directory, "*." + originalExtension);
foreach (var file in files)
{
using (FileStream streamFile = new FileStream(file, FileMode.Open, FileAccess.ReadWrite))
{
using (MemoryStream codedMemory = new MemoryStream())
{
streamFile.CopyTo(codedMemory);
byte[] fileArray = codedMemory.ToArray();
byte[] output = new byte[fileArray.Length];
for (int i = 0; i < fileArray.Length; i++)
output[i] = (byte)(fileArray[i]^~hash[(i + 1) % hash.Length]);
using (MemoryStream memoryCodificado = new MemoryStream(output))
{
string fileDestination = Path.ChangeExtension(file, "." + finalExtension);
if (File.Exists(fileDestination))
File.Delete(fileDestination);
using (FileStream arquivoFinal = new FileStream(fileDestination, FileMode.Create, FileAccess.ReadWrite))
{
memoryCodificado.Position = 0;
memoryCodificado.CopyTo(arquivoFinal);
}
}
}
}
}
}
}
est Ci-dessous le code Delphi:
procedure TfrmEncodeDecode.btnCodificarArquivoClick(Sender: TObject);
const
Hash: string = 'laki#~~2p3fijo3ij881*2f-|- a`asso`wpeofi#[email protected]';
var
counter, i: Integer;
bufferStream : ^Byte;
streamSize: Int64;
streamFile: TFileStream;
listFiles: TStringDynArray;
codedMemory: TMemoryStream;
directory, originalExtension, finalExtension, fileDestination: string;
begin
if (cbxConverter.Checked) then
begin
originalExtension := 'mp3';
finalExtension := 'mpc';
end
else
begin
originalExtension := 'mpc';
finalExtension := 'mp3';
end;
directory := String(edtFrase.Text).Trim;
if (not TDirectory.Exists(directory, true)) then
raise Exception.Create('Diretório não existe => ' + directory);
listFiles := TDirectory.GetFiles(directory, '*.' + originalExtension);
if (Length(listFiles) > 0) then
begin
for counter := 0 to Pred(Length(listFiles)) do
begin
streamFile := TFileStream.Create(listFiles[counter], fmOpenRead, fmShareExclusive);
try
codedMemory := TMemoryStream.Create;
try
codedMemory.CopyFrom(streamFile, streamFile.Size);
fileDestination := TPath.ChangeExtension(listFiles[counter], '.' + finalExtension);
if (TFile.Exists(fileDestination, true)) then
TFile.Delete(fileDestination);
streamSize := codedMemory.Size;
bufferStream := codedMemory.Memory;
i := 0;
while (i < streamSize) do
begin
bufferStream^ := Byte(ord (bufferStream^) xor not (Ord (Hash[I mod Length (Hash) + 1])));
Inc(bufferStream);
Inc(i);
end;
codedMemory.SaveToFile(fileDestination);
finally
codedMemory.Free;
end;
finally
streamFile.Free;
end;
end;
end;
end;
EDIT
compléme En réponse à la question, vous trouverez ci-dessous le code de la chaîne encoder/décoder. Faire cela pour la chaîne, je peux coder en C# et le décoder Delphi sans problème:
private string EncodeDecode(string str)
{
Encoding ANSI = Encoding.GetEncoding(1252);
byte[] hash = ANSI.GetBytes(@"laki#~~2p3fijo3ij881*2f-|- a`asso`wpeofi#[email protected]");
byte[] input = ANSI.GetBytes(str);
byte[] output = new byte[input.Length];
for (int i = 0; i < input.Length; i++)
output[i] = (byte)(input[i]^~hash[(i + 1) % hash.Length]);
return ANSI.GetString(output);
}
et ci-dessous est le code Delphi
function TfrmEncodeDecode.EncodeDecode(palavra: AnsiString): AnsiString;
const
Hash: string = 'laki#~~2p3fijo3ij881*2f-|- a`asso`wpeofi#[email protected]';
var
I: Integer;
begin
Result := palavra;
for I := 1 to Length (Result) do
Result[I] := AnsiChar (ord (Result[I]) xor not (Ord (Hash[I mod Length (Hash) + 1])));
end;
EDIT
Après Ken` s commente, j'ai changé le côté Delphi pour que le hash soit converti en un tableau d'octets, comme le montre le code ci-dessous, et maintenant le mp3 joue effectivement lorsqu'il est encodé en C# et décodé en Delphi, mais la chanson ressemble à un disque rayé quand ça joue. Ci-dessous le nouveau code Delphi:
procedure TfrmEncodeDecode.btnCodificarArquivoClick(Sender: TObject);
const
Hash: string = 'laki#~~2p3fijo3ij881*2f-|- a`asso`wpeofi#[email protected]';
var
counter, i: Integer;
bufferStream : ^Byte;
streamSize: Int64;
aHash: TArray<Byte>;
streamFile: TFileStream;
listFiles: TStringDynArray;
codedMemory: TMemoryStream;
directory, originalExtension, finalExtension, fileDestination: string;
begin
aHash := TEncoding.ANSI.GetBytes(Hash);
if (cbxConverter.Checked) then
begin
originalExtension := 'mp3';
finalExtension := 'mpc';
end
else
begin
originalExtension := 'mpc';
finalExtension := 'mp3';
end;
directory := String(edtFrase.Text).Trim;
if (not TDirectory.Exists(directory, true)) then
raise Exception.Create('Diretório não existe => ' + directory);
listFiles := TDirectory.GetFiles(directory, '*.' + originalExtension);
if (Length(listFiles) > 0) then
begin
for counter := 0 to Pred(Length(listFiles)) do
begin
streamFile := TFileStream.Create(listFiles[counter], fmOpenRead, fmShareExclusive);
try
codedMemory := TMemoryStream.Create;
try
codedMemory.CopyFrom(streamFile, streamFile.Size);
fileDestination := TPath.ChangeExtension(listFiles[counter], '.' + finalExtension);
if (TFile.Exists(fileDestination, true)) then
TFile.Delete(fileDestination);
streamSize := codedMemory.Size;
bufferStream := codedMemory.Memory;
i := 0;
while (i < streamSize) do
begin
bufferStream^ := Byte(ord (bufferStream^) xor not (Ord (aHash[I mod Length (aHash) + 1])));
Inc(bufferStream);
Inc(i);
end;
codedMemory.SaveToFile(fileDestination);
finally
codedMemory.Free;
end;
finally
streamFile.Free;
end;
end;
end;
end;
J'ai vérifié chacun des 62 octets dans le tableau, on compare les valeurs de C# avec les valeurs Delphi, et ils correspondent parfaitement, il est donc pas un problème de codage lors de la conversion la chaîne au tableau Byte
* il ne fonctionne pas * est une description du problème tout à fait dénué de sens. Comment ** spécifiquement ** ça * ne marche pas *? Vous devez [modifier] votre question et indiquer clairement le problème que vous rencontrez avec les blocs de code que vous avez publiés. Vous n'avez encore rien expliqué. –
Lorsque j'essaie de lire le mp3 encodé en C# après décodage en Delphi, il ne joue pas. Il woks avec des chaînes simples, mais maintenant avec des fichiers. Si je code/décode en Delphi, le mp3 joue. Si je code/décode en C#, le mp3 joue – Pascal
Comme je l'ai dit, [edit] votre question et ** expliquez clairement le problème ** dans la question elle-même. L'enterrer dans les commentaires n'est pas plus utile que de dire que ça ne marche pas *. –