YAmaGNZさんも指摘されていますが、頭にゼロが来ていませんか?
前後で配列サイズはあっていますか?
使用できる最も少ないバイト数を使用して、この BigInteger の値をバイト配列として返します。
BigInteger.ToByteArray メソッド (System.Numerics) | Microsoft Learn
先頭ゼロさえ来なければあってそうな気もしますが、そうでもないなら再現する(短めの)データが欲しいですね^^;
.NET Core3.1は既にサポート切れですので、.NET7を(C#8.0に落として)使用しました^^
.NET および .NET Core オフィシャル サポート ポリシー
cs
1 using System ;
2 using System . Linq ;
3 using System . Numerics ;
4
5
6 namespace Qrxl0vycu5kh9f9
7 {
8 class Program
9 {
10 static void Main ( )
11 {
12 {
13 // ゼロから始まると短くなってしまう
14 var a = new byte [ ] { 0 , 1 , 2 , 3 } ;
15 var b = new BigInteger ( a , true , true ) ;
16 var c = b . ToByteArray ( true , true ) ;
17 Console . WriteLine ( string . Join ( ", " , c ) ) ; // 1, 2, 3
18 }
19
20
21 {
22 // チャンク先頭にゼロが来るので3byte減った
23 var a = Enumerable . Range ( 0 , 533 ) . Select ( i => ( byte ) ( i % 256 ) ) . ToArray ( ) ;
24 var b = bint2by ( by2bint ( a ) ) ;
25 Print ( a , b ) ; // a.Length:533 b.Length:530 SequenceEqual:False
26 }
27 {
28 // 1個目チャンクの先頭ゼロで1byte減った
29 var a = Enumerable . Range ( 0 , 533 ) . Select ( i => ( byte ) ( i % 200 ) ) . ToArray ( ) ;
30 var b = bint2by ( by2bint ( a ) ) ;
31 Print ( a , b ) ; // a.Length:533 b.Length:532 SequenceEqual:False
32 }
33 {
34 // チャンク先頭にゼロが来なければあってそう?
35 var a = Enumerable . Range ( 1 , 533 ) . Select ( i => ( byte ) ( i % 256 ) ) . ToArray ( ) ;
36 var b = bint2by ( by2bint ( a ) ) ;
37 Print ( a , b ) ; // a.Length:533 b.Length:533 SequenceEqual:True
38 }
39
40
41 try
42 {
43 // 最終チャンクに先頭ゼロが来ると(トータルサイズを知らないと)戻しようがない
44 var a = Enumerable . Range ( 0 , 533 ) . Select ( i => ( byte ) ( i % 256 ) ) . ToArray ( ) ;
45 var b = BigIntArray2ByteArray ( ByteArray2BigIntArray ( a ) ) ;
46 Print ( a , b ) ;
47 }
48 catch ( Exception e )
49 {
50 Console . WriteLine ( $" { e . Message } \n" ) ; // 復元不可能なsourceです
51 }
52 {
53 // 最終チャンク以外の先頭ゼロは分割サイズを知っていれば戻せるが...
54 var a = Enumerable . Range ( 0 , 533 ) . Select ( i => ( byte ) ( i % 200 ) ) . ToArray ( ) ;
55 var b = BigIntArray2ByteArray ( ByteArray2BigIntArray ( a ) ) ;
56 Print ( a , b ) ; // a.Length:533 b.Length:533 SequenceEqual:True
57 }
58 {
59 var a = Enumerable . Range ( 1 , 533 ) . Select ( i => ( byte ) ( i % 256 ) ) . ToArray ( ) ;
60 var b = BigIntArray2ByteArray ( ByteArray2BigIntArray ( a ) ) ;
61 Print ( a , b ) ; // a.Length:533 b.Length:533 SequenceEqual:True
62 }
63 }
64
65 static BigInteger [ ] by2bint ( byte [ ] byArray )
66 {
67 var C = 256 ;
68 var bintArray = new BigInteger [ 0 ] ;
69
70 for ( var i = 0 ; i < ( double ) byArray . Length / C ; i ++ )
71 {
72 byte [ ] nowbyArray ;
73 if ( byArray . Length < ( i + 1 ) * C )
74 {
75 nowbyArray = new byte [ byArray . Length - i * C ] ;
76 Array . Copy ( byArray , i * C , nowbyArray , 0 , nowbyArray . Length ) ;
77 }
78 else
79 {
80 nowbyArray = new byte [ C ] ;
81 Array . Copy ( byArray , i * C , nowbyArray , 0 , C ) ;
82 }
83
84 Array . Resize ( ref bintArray , bintArray . Length + 1 ) ;
85 bintArray [ i ] = new BigInteger ( nowbyArray , true , true ) ;
86 }
87
88 return bintArray ;
89 }
90 static byte [ ] bint2by ( BigInteger [ ] bintArray )
91 {
92 var byArray = new byte [ 0 ] ;
93 foreach ( var bint in bintArray )
94 {
95 var nowbyArray = bint . ToByteArray ( true , true ) ;
96 var l = byArray . Length ;
97
98 Array . Resize ( ref byArray , byArray . Length + nowbyArray . Length ) ;
99 Array . Copy ( nowbyArray , 0 , byArray , l , nowbyArray . Length ) ;
100 }
101
102 return byArray ;
103 }
104
105
106
107 static BigInteger [ ] ByteArray2BigIntArray ( byte [ ] source , int size = 256 )
108 {
109 if ( source == null ) throw new ArgumentNullException ( nameof ( source ) ) ;
110 if ( size < 1 ) throw new ArgumentOutOfRangeException ( nameof ( size ) ) ;
111
112 if ( source . Length == 0 ) return Array . Empty < BigInteger > ( ) ;
113
114
115 var dest = new BigInteger [ ( source . Length + size - 1 ) / size ] ;
116
117 var span = source . AsSpan ( ) ;
118 for ( var i = 0 ; i < dest . Length - 1 ; i ++ )
119 {
120 dest [ i ] = new BigInteger ( span [ .. size ] , true , true ) ;
121 span = span [ size .. ] ;
122 }
123
124 if ( span [ 0 ] == 0 ) throw new ArgumentException ( "復元不可能なsourceです" ) ;
125
126 dest [ ^ 1 ] = new BigInteger ( span , true , true ) ;
127
128 return dest ;
129
130
131 // 先頭ゼロを無条件で弾いていいなら戻すのも楽なのだが...
132 //return source.Chunk(size).Select(x =>
133 //{
134 // if (x[0] == 0) throw new ArgumentException("チャンク先頭がゼロです");
135 // return new BigInteger(x, true, true);
136 //}).ToArray();
137 }
138 static byte [ ] BigIntArray2ByteArray ( BigInteger [ ] source , int size = 256 )
139 {
140 if ( source == null ) throw new ArgumentNullException ( nameof ( source ) ) ;
141 if ( size < 1 ) throw new ArgumentOutOfRangeException ( nameof ( size ) ) ;
142
143 if ( source . Length == 0 ) return Array . Empty < byte > ( ) ;
144
145
146 var dest = new byte [ source . Length * size ] ;
147 var length = 0 ;
148 for ( var i = 0 ; i < source . Length ; i ++ )
149 {
150 var array = source [ i ] . ToByteArray ( true , true ) ;
151 if ( size < array . Length ) throw new ArgumentException ( "sourceがsizeより大きいです" ) ;
152
153 if ( i < source . Length - 1 )
154 {
155 Array . Copy ( array , 0 , dest , length + size - array . Length , array . Length ) ;
156 length += size ;
157 }
158 else
159 {
160 Array . Copy ( array , 0 , dest , length , array . Length ) ;
161 length += array . Length ;
162 }
163 }
164 Array . Resize ( ref dest , length ) ;
165
166 return dest ;
167
168
169 // 先頭ゼロがないのであれば1行なのだが...
170 //return source.SelectMany(x => x.ToByteArray(true, true)).ToArray();
171 }
172
173
174 static void Print ( byte [ ] a , byte [ ] b )
175 => Console . WriteLine ( $"a.Length: { a . Length } b.Length: { b . Length } SequenceEqual: { a . SequenceEqual ( b ) } \n" ) ;
176 }
177 }