Advertisement
Guest User

Validating a banano address

a guest
Mar 21st, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { blake2b } from 'blakejs'
  2.  
  3. const ALPHABET = '13456789abcdefghijkmnopqrstuwxyz'
  4.  
  5. export default class Util {
  6.     // Extract banano address candidate from string, return null if not found
  7.     static extractAddress(rawString : string) : string | null {
  8.         let pattern : RegExp = new RegExp("(ban)(_)(1|3)[13456789abcdefghijkmnopqrstuwxyz]{59}", "g");
  9.         rawString = rawString.toLowerCase();
  10.         let matches : RegExpMatchArray | null = rawString.match(pattern)
  11.         if (matches == null) {
  12.             return null
  13.         }
  14.         return matches[0]
  15.     }
  16.  
  17.     static readChar(char: string): number {
  18.         const idx = ALPHABET.indexOf(char)
  19.      
  20.         if (idx === -1) {
  21.           throw new Error(`Invalid character found: ${char}`)
  22.         }
  23.      
  24.         return idx
  25.       }
  26.  
  27.     static decodeNanoBase32(input: string): Uint8Array {
  28.         const length = input.length
  29.         const leftover = (length * 5) % 8
  30.         const offset = leftover === 0 ? 0 : 8 - leftover
  31.      
  32.         let bits = 0
  33.         let value = 0
  34.      
  35.         let index = 0
  36.         let output = new Uint8Array(Math.ceil((length * 5) / 8))
  37.      
  38.         for (let i = 0; i < length; i++) {
  39.           value = (value << 5) | this.readChar(input[i])
  40.           bits += 5
  41.      
  42.           if (bits >= 8) {
  43.             output[index++] = (value >>> (bits + offset - 8)) & 255
  44.             bits -= 8
  45.           }
  46.         }
  47.         if (bits > 0) {
  48.           output[index++] = (value << (bits + offset - 8)) & 255
  49.         }
  50.      
  51.         if (leftover !== 0) {
  52.           output = output.slice(1)
  53.         }
  54.         return output
  55.     }
  56.  
  57.     // Validate banano address, return address if valid, false if invalid
  58.     static validateAddress(address : string) : string | boolean {
  59.         let parsedAddress : string | null = this.extractAddress(address)
  60.         if (parsedAddress == null) {
  61.             return false
  62.         }
  63.  
  64.         const publicKeyBytes = this.decodeNanoBase32(
  65.           (parsedAddress as string).substr(4, 52)
  66.         )
  67.         const checksumBytes = this.decodeNanoBase32(
  68.           (parsedAddress as string).substr(4 + 52)
  69.         )
  70.      
  71.         const computedChecksumBytes = blake2b(publicKeyBytes, null, 5).reverse()
  72.      
  73.         let valid = true;
  74.         for (let i = 0; i < checksumBytes.length; i++) {
  75.             if (checksumBytes[i] !== computedChecksumBytes[i]) {
  76.                 valid = false
  77.             }
  78.         }
  79.      
  80.         if (!valid) {
  81.             return false
  82.         }
  83.  
  84.         return parsedAddress      
  85.     }
  86. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement