2015-06-13 2 views
4

Следующая проблема: У меня есть программа C#, которая делает некоторое дешифрование на очень низком уровне. Я использовал инструмент, чтобы преобразовать большую часть кода C# в Java, который работал для большинства вещей, но когда дело доходит до таких частей низкого уровня, инструмент выходит из строя. Следующая структура данных используется внутри:Port C# Code to Java

[StructLayout(LayoutKind.Explicit)] 
     private struct ByteUInt 
     { 
      [FieldOffset(0)] 
      public byte Byte0; 

      [FieldOffset(1)] 
      public byte Byte1; 

      [FieldOffset(2)] 
      public byte Byte2; 

      [FieldOffset(3)] 
      public byte Byte3; 

      [FieldOffset(0)] 
      public uint FullUint; 
     } 

В программе, байты и UINT внутри этой структуры изменяются в несколько раз по отдельности, например, например MyByteUint.Byte0 &= someByte; или MyMyteUint.FullUint = someByte & 0x0F или некоторые другие побитовые операции. Поскольку uint ссылается на ту же память, что и на 4 байта, если я меняю один из них, uint тоже изменится и наоборот.

Поскольку в Java нет реальных указателей, я не знаю, как лучше переносить такую ​​вещь на Java, потому что я не могу напрямую ссылаться на память. Есть ли какое-либо решение иначе, чем создание класса с геттерами и сеттерами, делающими поля частными и обновляющими uint/bytes при изменении других значений?

Спасибо за ваш вклад.

+1

Следует отметить, что байты подписаны в Java (от -128 до 127), но не в C# (если вы не используете 'sbyte'.) – Cyral

+0

Спасибо за эту информацию. В моем случае я думаю, что это не большая проблема, потому что их представление бит должно быть одинаковым. – trixn

ответ

3

Я предполагаю, что приведенная выше структура фактически используется для наложения (эффективно) массива битов в качестве массива byte или массива int.

Вы не можете сделать это на Java. Ваш выбор:

  • Моделируйте его как массив byte и получите удар производительности, когда вы делаете индексированное копирование.
  • Моделировать его как массив int, а также использовать бит-сдвиг и маскировку для выполнения байтовых операций.
  • Использовать собственный код; то есть кодировать/дешифровать на C или C++ и использовать JNI или JNA или аналогичные для вызова этого кода из Java.

Вы также можете ознакомиться с классами IntBuffer или ByteBuffer. Это (IMO) вряд ли улучшит производительность для ваших операций шифрования/дешифрования, сделанных изолированно, но когда вы объедините их с NIO I/O (в качестве альтернативы копированию I/O + в библиотеку/в массиве), вы можете стать лучше представление.


Но также стоит отметить, что все это имеет запах преждевременной оптимизации. Я бы порекомендовал сначала написать Java-код простейшим способом, а позже позаботиться о производительности ... если измерение говорит вам, что это действительно опасно.

+0

Да, эта структура используется так, как вы ее описали. Я получаю бит-поток в качестве входных данных с частями его зашифрованных. Структура накладывает эти биты и является всего лишь помощником для выполнения необходимых операций с битами. Спасибо за ваш ответ, я поближе рассмотрю эти варианты. Производительность на самом деле не для меня. У меня просто была программа, уже написанная на Java и алгоритм de/encryption в C#, и я искал простой способ реализовать это на Java без изменения всего алгоритма. – trixn

+0

В этом случае выберите между 'byte []' или 'int []'. Вы не будете «изменять весь алгоритм» ... просто переписываете или преобразуете его. –

+0

Да, это не «изменение алгоритма». Извините, английский не мой родной язык, поэтому мне трудно выразить точные вещи, которые я имею в виду. Я имел в виду это как изменение архитектуры, потому что код C# имеет очень много строк кода, и у меня нет много времени.Это просто дополнение к программе Java для моих исследований: D – trixn