@@ -266,36 +266,50 @@ impl SupportsFastDecodeAndEncode for Base58Wrapper {
266266 return Ok ( ( ) ) ;
267267 }
268268
269- // Convert bytes to big integer
270- let mut num: Vec < u32 > = Vec :: new ( ) ;
269+ // Convert bytes to big integer (Vec<u32> in little-endian format)
270+ let mut num = Vec :: with_capacity ( input_trimmed . len ( ) . div_ceil ( 4 ) + 1 ) ;
271271 for & byte in input_trimmed {
272- let mut carry = byte as u32 ;
272+ let mut carry = byte as u64 ;
273273 for n in & mut num {
274- let tmp = ( * n as u64 ) * 256 + carry as u64 ;
274+ let tmp = ( * n as u64 ) * 256 + carry;
275275 * n = tmp as u32 ;
276- carry = ( tmp >> 32 ) as u32 ;
276+ carry = tmp >> 32 ;
277277 }
278278 if carry > 0 {
279- num. push ( carry) ;
279+ num. push ( carry as u32 ) ;
280280 }
281281 }
282282
283283 // Convert to base58
284- let mut result = Vec :: new ( ) ;
284+ let mut result = Vec :: with_capacity ( ( input_trimmed . len ( ) * 138 / 100 ) + 1 ) ;
285285 let alphabet = self . alphabet ( ) ;
286286
287- while !num. is_empty ( ) && num. iter ( ) . any ( |& n| n != 0 ) {
287+ // Optimized check: stop when all elements are zero
288+ while !num. is_empty ( ) {
289+ // Check if we're done (all zeros)
290+ let mut all_zero = true ;
288291 let mut carry = 0u64 ;
292+
289293 for n in num. iter_mut ( ) . rev ( ) {
290294 let tmp = carry * ( 1u64 << 32 ) + * n as u64 ;
291295 * n = ( tmp / 58 ) as u32 ;
292296 carry = tmp % 58 ;
297+ if * n != 0 {
298+ all_zero = false ;
299+ }
293300 }
301+
294302 result. push ( alphabet[ carry as usize ] ) ;
295303
296- // Remove leading zeros
297- while num. last ( ) == Some ( & 0 ) && num. len ( ) > 1 {
298- num. pop ( ) ;
304+ if all_zero {
305+ break ;
306+ }
307+
308+ // Trim trailing zeros less frequently
309+ if num. len ( ) > 1 && result. len ( ) % 8 == 0 {
310+ while num. last ( ) == Some ( & 0 ) && num. len ( ) > 1 {
311+ num. pop ( ) ;
312+ }
299313 }
300314 }
301315
@@ -305,15 +319,18 @@ impl SupportsFastDecodeAndEncode for Base58Wrapper {
305319 }
306320
307321 // Add result (reversed because we built it backwards)
308- for byte in result. into_iter ( ) . rev ( ) {
322+ for & byte in result. iter ( ) . rev ( ) {
309323 output. push_back ( byte) ;
310324 }
311325
312326 Ok ( ( ) )
313327 }
314328
315329 fn unpadded_multiple ( & self ) -> usize {
316- 1 // Base58 doesn't use padding
330+ // Base58 must encode the entire input as one big integer, not in chunks
331+ // Use a very large value to effectively disable chunking, but avoid overflow
332+ // when multiplied by ENCODE_IN_CHUNKS_OF_SIZE_MULTIPLE (1024) in base_common
333+ usize:: MAX / 2048
317334 }
318335
319336 fn valid_decoding_multiple ( & self ) -> usize {
0 commit comments