@@ -11,8 +11,8 @@ namespace NCMDumpCore
11
11
public class NCMDumper
12
12
{
13
13
private readonly int vectorSize = Vector256 < byte > . Count ;
14
- private readonly byte [ ] coreKey = { 0x68 , 0x7A , 0x48 , 0x52 , 0x41 , 0x6D , 0x73 , 0x6F , 0x35 , 0x6B , 0x49 , 0x6E , 0x62 , 0x61 , 0x78 , 0x57 } ;
15
- private readonly byte [ ] metaKey = { 0x23 , 0x31 , 0x34 , 0x6C , 0x6A , 0x6B , 0x5F , 0x21 , 0x5C , 0x5D , 0x26 , 0x30 , 0x55 , 0x3C , 0x27 , 0x28 } ;
14
+ private readonly byte [ ] coreKey = [ 0x68 , 0x7A , 0x48 , 0x52 , 0x41 , 0x6D , 0x73 , 0x6F , 0x35 , 0x6B , 0x49 , 0x6E , 0x62 , 0x61 , 0x78 , 0x57 ] ;
15
+ private readonly byte [ ] metaKey = [ 0x23 , 0x31 , 0x34 , 0x6C , 0x6A , 0x6B , 0x5F , 0x21 , 0x5C , 0x5D , 0x26 , 0x30 , 0x55 , 0x3C , 0x27 , 0x28 ] ;
16
16
17
17
private bool VerifyHeader ( ref MemoryStream ms )
18
18
{
@@ -35,7 +35,7 @@ private byte[] ReadRC4Key(ref MemoryStream ms)
35
35
ms . Read ( buffer ) ;
36
36
37
37
//SIMD XOR 0x64
38
- Vector256 < byte > xor = Vector256 . Create ( 0x64646464 ) . AsByte ( ) ;
38
+ Vector256 < byte > xor = Vector256 . Create ( ( byte ) 0x64 ) ;
39
39
int i ;
40
40
for ( i = 0 ; i <= buffer . Length - vectorSize ; i += vectorSize )
41
41
{
@@ -49,11 +49,13 @@ private byte[] ReadRC4Key(ref MemoryStream ms)
49
49
}
50
50
51
51
// decrypt keybox data
52
- using ( var decrypter = new AesCng ( ) { Key = coreKey , Mode = CipherMode . ECB } . CreateDecryptor ( ) )
52
+ using ( Aes aes = Aes . Create ( ) )
53
53
{
54
- buffer = decrypter . TransformFinalBlock ( buffer . ToArray ( ) , 0 , buffer . Length ) . Skip ( 17 ) . ToArray ( ) ; // 17 = len("neteasecloudmusic")
54
+ aes . Mode = CipherMode . ECB ;
55
+ aes . Key = coreKey ;
56
+ var cleanText = aes . DecryptEcb ( buffer . ToArray ( ) , PaddingMode . PKCS7 ) . ToArray ( ) [ 17 ..] ;
57
+ return cleanText ;
55
58
}
56
- return buffer . ToArray ( ) ;
57
59
}
58
60
59
61
private MetaInfo ReadMeta ( ref MemoryStream ms )
@@ -65,7 +67,7 @@ private MetaInfo ReadMeta(ref MemoryStream ms)
65
67
ms . Read ( buffer ) ;
66
68
67
69
//SIMD XOR 0x63
68
- Vector256 < byte > xor = Vector256 . Create ( 0x63636363 ) . AsByte ( ) ;
70
+ Vector256 < byte > xor = Vector256 . Create ( ( byte ) 0x63 ) ;
69
71
int i ;
70
72
for ( i = 0 ; i <= buffer . Length - vectorSize ; i += vectorSize )
71
73
{
@@ -81,21 +83,23 @@ private MetaInfo ReadMeta(ref MemoryStream ms)
81
83
buffer = System . Convert . FromBase64String ( Encoding . ASCII . GetString ( buffer . ToArray ( ) [ 22 ..] ) ) ;
82
84
83
85
// decrypt meta data which is a json contains info of the song
84
- using ( var cryptor = new AesCng ( ) { Key = metaKey , Mode = CipherMode . ECB } . CreateDecryptor ( ) )
86
+ using ( Aes aes = Aes . Create ( ) )
85
87
{
86
- buffer = cryptor . TransformFinalBlock ( buffer . ToArray ( ) , 0 , buffer . Length ) ;
87
- var MetaJsonString = Encoding . UTF8 . GetString ( buffer ) . Replace ( "music:" , "" ) ;
88
+ aes . Mode = CipherMode . ECB ;
89
+ aes . Key = metaKey ;
90
+ var cleanText = aes . DecryptEcb ( buffer . ToArray ( ) , PaddingMode . PKCS7 ) ;
91
+ var MetaJsonString = Encoding . UTF8 . GetString ( cleanText [ 6 ..] ) ;
88
92
MetaInfo metainfo = JsonSerializer . Deserialize < MetaInfo > ( MetaJsonString ) ;
89
93
return metainfo ;
90
94
}
91
95
}
92
96
93
97
private async Task < byte [ ] > ReadAudioData ( MemoryStream ms , byte [ ] Key )
94
98
{
95
- using ( RC4_NCM_Stream rc4s = new RC4_NCM_Stream ( ms , Key ) )
99
+ using ( RC4_NCM_Stream rc4s = new ( ms , Key ) )
96
100
{
97
101
byte [ ] data = new byte [ ms . Length - ms . Position ] ;
98
- Memory < byte > m_data = new Memory < byte > ( data ) ;
102
+ Memory < byte > m_data = new ( data ) ;
99
103
await rc4s . ReadAsync ( m_data ) ;
100
104
return data ;
101
105
}
@@ -122,7 +126,7 @@ private void AddTag(string fileName, byte[]? ImgData, MetaInfo metainfo)
122
126
}
123
127
}
124
128
125
- //Add more infomation
129
+ //Add more information
126
130
tagfile . Tag . Title = metainfo . musicName ;
127
131
tagfile . Tag . Performers = metainfo . artist . Select ( x => x [ 0 ] ) . ToArray ( ) ;
128
132
tagfile . Tag . Album = metainfo . album ;
@@ -132,7 +136,7 @@ private void AddTag(string fileName, byte[]? ImgData, MetaInfo metainfo)
132
136
133
137
private byte [ ] ? FetchUrl ( Uri uri )
134
138
{
135
- HttpClient client = new HttpClient ( ) ;
139
+ HttpClient client = new ( ) ;
136
140
try
137
141
{
138
142
var response = client . GetAsync ( uri ) . Result ;
@@ -182,7 +186,7 @@ public async Task<bool> ConvertAsync(string path)
182
186
}
183
187
184
188
//Read all bytes to ram.
185
- MemoryStream ms = new MemoryStream ( await System . IO . File . ReadAllBytesAsync ( path ) ) ;
189
+ MemoryStream ms = new ( await System . IO . File . ReadAllBytesAsync ( path ) ) ;
186
190
187
191
//Verify Header
188
192
if ( ! VerifyHeader ( ref ms ) )
@@ -201,9 +205,7 @@ public async Task<bool> ConvertAsync(string path)
201
205
MetaInfo metainfo = ReadMeta ( ref ms ) ;
202
206
203
207
//CRC32 Check
204
- var crc32bytes = new byte [ 4 ] ;
205
- ms . Read ( crc32bytes , 0 , crc32bytes . Length ) ;
206
- var crc32len = MemoryMarshal . Read < int > ( crc32bytes ) ;
208
+ uint crc32 = ReadUint32 ( ref ms ) ;
207
209
208
210
// skip 5 character,
209
211
ms . Seek ( 5 , SeekOrigin . Current ) ;
@@ -226,16 +228,15 @@ public async Task<bool> ConvertAsync(string path)
226
228
byte [ ] AudioData = await ReadAudioData ( ms , RC4Key ) ;
227
229
228
230
//Flush Audio Data to disk drive
229
- string OutputPath = path . Substring ( 0 , path . LastIndexOf ( "." ) ) ;
231
+ string OutputPath = path [ .. path . LastIndexOf ( '.' ) ] ;
230
232
231
233
string format = metainfo . format ;
232
234
if ( format is null or "" ) format = "mp3" ;
233
235
await System . IO . File . WriteAllBytesAsync ( $ "{ OutputPath } .{ format } ", AudioData ) ;
234
236
235
237
//Add tag and cover
236
238
await Task . Run ( ( ) => AddTag ( $ "{ OutputPath } .{ format } ", ImageData , metainfo ) ) ;
237
- ms . Flush ( ) ;
238
- ms . Close ( ) ;
239
+ await ms . DisposeAsync ( ) ;
239
240
return true ;
240
241
}
241
242
}
0 commit comments