Byte Array in Bit's und zurück

  • VB.NET
  • .NET 2.0

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von exc-jdbi.

    Byte Array in Bit's und zurück

    Guten Abend, ich tüftele seit nun gut 3 Tagen an folgenden Problem herum,

    Mein Ziel ist es, ein Byte Arry in seine Bit's, dargestellt in Nullen und Einsen zu zerlegen, und diese dann wieder zurück.
    Ich erwarte selbstverständlich nicht das mir hier jemand den Code fertig stellt, und mir eine komplett gefixte Version zu schickt,
    und doch würde ich mich sehr über Anhaltspunkte freuen, wo mein Fehler liegen könnte, da ich wirklich schon lange dran rum bastle, und der Code jetzt endlich,
    ohne einen Fehler auszugeben läuft.

    VB.NET-Quellcode

    1. Private Sub DebugSub
    2. Dim b0 As Byte() = System.IO.File.ReadAllBytes(Application.StartupPath & "\TestFile.exe")
    3. Dim s0 As String = ByteToBits(b0)
    4. Dim b1 As Byte() = BitsIntToByteArray(s0)
    5. System.IO.File.WriteAllBytes(Application.StartupPath & "\TestFileRebuild.exe", b1)
    6. MsgBox("done")
    7. End Sub
    8. Private Function ByteToBits(ByVal b0 As Byte()) As String 'from the Internet
    9. Dim OutPutS1 As String
    10. For Each b1 As Byte In b0
    11. Dim i As Integer
    12. Dim xx(0 To 7) As Byte
    13. For i = 0 To 7
    14. If b1 And 2 ^ i Then xx(i) = 1 Else xx(i) = 0
    15. OutPutS1 = OutPutS1 & CStr(xx(i))
    16. Next
    17. Next
    18. Return OutPutS1
    19. OutPutS1 = Nothing
    20. End Function
    21. Private Function BitsIntToByteArray(ByVal s0 As String) As Byte()
    22. Dim LiByte0 As New List(Of Byte)
    23. For i As Integer = 0 To s0.Length - 1 Step 8
    24. Dim s1 As String = s0.Substring(i, 7) ' or s0.Substring(i, 8) ? starts @ 0 or 1?
    25. Dim b0 As Byte = Convert.ToByte(s1, 2)
    26. LiByte0.Add(b0)
    27. Next
    28. Return LiByte0.ToArray
    29. End Function


    Komme aktuell echt nicht weiter, der Output hat im Hex Editor gewisse Ähnlichkeiten, aber nur von der "Form" her, nicht vom Inhalt, freue mich über jeden Tipp. ?(

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „voubekai“ ()

    Hallo @voubekai

    Ich würde da ein bisschen optimierter vorgehen. Das Framework besitz dazu geeignete Bortmittel.

    In deiner Function ByteToBits mit Stringbuilder gelöst

    VB.NET-Quellcode

    1. res.Append(String.Format("{0:d8}", CUInt(Convert.ToString(bb, 2))))


    In deiner Funktion BitsIntToByteArray

    VB.NET-Quellcode

    1. tmp = s.Substring(i, 8)
    2. res.Add(Convert.ToByte(tmp, 2))


    und dann sollte es klappen ansosnten melde dich nochmals

    Ich hoffe jetzt nicht, dass der Fehler beim lesen von der HDD oder Speichern auf die HDD entstanden ist.


    Freundliche Grüsse

    exc-jdbi
    Erstmal dankeschön @exc-jdbi

    Habe bis jetzt immer nur gehört, man solle so wenig externe Funktionen ansprechen wie möglich, das senkt zwar oftmals die Geschwindigkeit, kann aber die Kompatibilität erhöhen,
    deshalb bin ich nicht sehr vertraut mit System.Text, sowie mit der String.Format Funktion, mit welcher ich noch nie gearbeitet habe,
    dein bb ist ein Boolean, kann ich dort als Input den aktuellen Byte setzen? In etwa so?

    VB.NET-Quellcode

    1. Private Function ByteToBits0excjdbi(ByVal b0 As Byte()) As String
    2. Dim SB0 As New System.Text.StringBuilder
    3. For Each b1 As Byte In b0
    4. Dim i As Integer
    5. Dim xx(0 To 7) As Byte
    6. For i = 0 To 7
    7. If b1 And 2 ^ i Then xx(i) = 1 Else xx(i) = 0
    8. SB0.Append(String.Format("{0:d8}", CUInt(Convert.ToString(xx(i), 2))))
    9. Next
    10. Next
    11. Return SB0.ToString
    12. End Function


    Wen ich das durch laufen lasse, hat der Output eine völlig neue/andere/falsche Dateigröße!?! ?(

    Oder soll ich mir einfach nur den Stringbuilder anschauen? Mag ja sein, das es schneller geht, wen ich

    VB.NET-Quellcode

    1. SB0.Append(CStr(xx(i)))
    nutze. ?(

    Der zweite Punkt ist klar, hätte ich auch noch entsprechend bearbeitet, war halt die ganze zeit noch am Debuggen, und umstellen, deshalb die Zwischenspeicherung des wertes...
    Edit: Aus deinem Code schließe ich, das der Substring wirklich erst bei 1 beginnt!?!

    Ich glaube nur, das es Primär erstmal überhaupt nicht um Optimierung geht, sondern viel mehr darum, das der Code einen Fehler haben muss, weil er falschen Output liefert... :huh:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „voubekai“ ()

    die von exc-jdb vorgeschlagene Methode konvertiert immer ein ganzes Byte nach String.
    Da also für jedes Byte nochmal eine innere Schleife anzusetzen für jedes Bit kann nur Wirrsal stiften.
    probierma einfach

    VB.NET-Quellcode

    1. Private Function ByteToBits0excjdbi(ByVal b0 As Byte()) As String
    2. Dim SB0 As New System.Text.StringBuilder
    3. For Each b1 As Byte In b0
    4. SB0.Append(String.Format("{0:d8}", CUInt(Convert.ToString(b1, 2))))
    5. Next
    6. Return SB0.ToString
    7. End Function
    habe es kurz schnell geschrieben wie ich es meine

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Imports System.Text
    4. Public Module Module1
    5. Dim rng As New Random
    6. Public Sub Main()
    7. Dim size As Int32 = 100
    8. Dim b = CreateByteArray(size)
    9. Dim sw As New Stopwatch
    10. sw.Start()
    11. Dim s = ByteToBits2(b)
    12. sw.Stop()
    13. Console.WriteLine("Time: {0}ms", sw.ElapsedMilliseconds)
    14. Dim bol As Boolean = False
    15. sw = New Stopwatch
    16. sw.Start()
    17. Dim bb = BitsToByteArray(s)
    18. sw.Stop()
    19. Console.WriteLine("Time: {0}ms", sw.ElapsedMilliseconds)
    20. If Equals(b, bb) Then
    21. bol = True
    22. End If
    23. Console.WriteLine(bol)
    24. Console.ReadLine()
    25. End Sub
    26. Private Function BitsToByteArray(ByVal s As String) As Byte()
    27. If Not String.IsNullOrEmpty(s) Then
    28. Dim tmp As String
    29. Dim res As New List(Of Byte)(s.Length \ 8)
    30. For i As Int32 = 0 To s.Length - 1 Step 8
    31. tmp = s.Substring(i, 8)
    32. res.Add(Convert.ToByte(tmp, 2))
    33. Next
    34. Return res.ToArray
    35. End If
    36. Return Nothing
    37. End Function
    38. Private Function ByteToBits(ByVal b As Byte()) As String
    39. If (b IsNot Nothing) AndAlso (b.Length > 0) Then
    40. Dim res As New StringBuilder(8 * b.Length)
    41. For Each bb As Byte In b
    42. res.Append(New StringBuilder(CType(Convert.ToString(bb, 2), Int32).ToString("d8")))
    43. Next
    44. Return res.ToString
    45. End If
    46. Return Nothing
    47. End Function
    48. Private Function CreateByteArray(ByVal size As Int32) As Byte()
    49. If size > 0 Then
    50. Dim res = New Byte(size - 1) {}
    51. rng.NextBytes(res)
    52. Return res
    53. End If
    54. Return Nothing
    55. End Function
    56. Private Function Equals(ByVal b1() As Byte, ByVal b2() As Byte) As Boolean
    57. If b1 IsNot Nothing AndAlso b2 IsNot Nothing Then
    58. If b1.Length > 0 AndAlso b1.Length = b2.Length Then
    59. For i As Int32 = 0 To b1.Length - 1
    60. If Not b1(i) = b2(i) Then Return False
    61. Next
    62. Return True
    63. End If
    64. End If
    65. Return False
    66. End Function
    67. End Module


    Hab es noch ein klein wenig angepsst, damit es ein bisschen schneller lauft.


    Freundliche Grüsse

    exc-jdbi
    Diese Methode:

    VB.NET-Quellcode

    1. Private Function Equals(ByVal b1() As Byte, ByVal b2() As Byte) As Boolean
    2. If b1 IsNot Nothing AndAlso b2 IsNot Nothing Then
    3. If b1.Length > 0 AndAlso b1.Length = b2.Length Then
    4. For i As Int32 = 0 To b1.Length - 1
    5. If Not b1(i) = b2(i) Then Return False
    6. Next
    7. Return True
    8. End If
    9. End If
    10. Return False
    11. End Function
    braucht man nicht - weil da gibts schon:

    VB.NET-Quellcode

    1. [Imports System.Linq]
    2. b1.SequenceEquals(b2)

    voubekai schrieb:

    Habe bis jetzt immer nur gehört, man solle so wenig externe Funktionen ansprechen wie möglich, das senkt zwar oftmals die Geschwindigkeit, kann aber die Kompatibilität erhöhen,

    Keine Ahnung wer sowas behauptet, ich meine du hast die Abhängigkeit zu .Net allein dadurch, dass du die Sprache C# verwendest, wenn du dann Standard dinge ausm .Net Framework verwendest, dann verlierst du höchstens Kompatibilität zu älteren Frameworkversionen, aber die meisten Funktionen sind bereits seit Ewigkeiten vorhanden. Ohne explizite Anforderung eines Kundens würde ich nicht unbedingt auf ein altes Framework setzen.

    Jetzt aber erstmal die Frage, was willst du denn mit diesen "Bits", denn offensichtlich wandelst du es nicht in Bits um, sondern in eine Bitdarstellung als string. Für reine Darstellung ist das schön und gut, für alles andere nicht so, da müsste man mit Bitshift hin um einzelne bits auszulesen/zu verändern...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---