URI: 
       tnew seed_version: remove whitespaces only between CJK characters - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit cef75e9e7ba3bf96415c2dac9e2e53a3c198f096
   DIR parent 1df007483e4c402cfcd8da098fd425142d9d3bcc
  HTML Author: ThomasV <thomasv@gitorious>
       Date:   Sat, 13 Sep 2014 19:31:05 +0200
       
       new seed_version: remove whitespaces only between CJK characters
       
       Diffstat:
         M gui/qt/installwizard.py             |       5 ++---
         M lib/bitcoin.py                      |       2 +-
         M lib/mnemonic.py                     |      67 +++++++++++++++++++++++++------
         M lib/version.py                      |       2 +-
       
       4 files changed, 59 insertions(+), 17 deletions(-)
       ---
   DIR diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py
       t@@ -16,7 +16,7 @@ from amountedit import AmountEdit
        import sys
        import threading
        from electrum.plugins import run_hook
       -
       +from electrum.mnemonic import prepare_seed
        
        MSG_ENTER_ANYTHING    = _("Please enter a wallet seed, a master public key, a list of Bitcoin addresses, or a list of private keys")
        MSG_SHOW_MPK          = _("This is your master public key")
       t@@ -114,8 +114,7 @@ class InstallWizard(QDialog):
                r = self.enter_seed_dialog(MSG_VERIFY_SEED, sid, func)
                if not r:
                    return
       -
       -        if r != seed:
       +        if prepare_seed(r) != prepare_seed(seed):
                    QMessageBox.warning(None, _('Error'), _('Incorrect seed'), _('OK'))
                    return False
                else:
   DIR diff --git a/lib/bitcoin.py b/lib/bitcoin.py
       t@@ -150,7 +150,7 @@ hmac_sha_512 = lambda x,y: hmac.new(x, y, hashlib.sha512).digest()
        
        def is_new_seed(x, prefix=version.SEED_BIP44):
            import mnemonic
       -    x = mnemonic.Mnemonic.prepare_seed(x)
       +    x = mnemonic.prepare_seed(x)
            s = hmac_sha_512("Seed version", x.encode('utf8')).encode('hex')
            return s.startswith(prefix)
        
   DIR diff --git a/lib/mnemonic.py b/lib/mnemonic.py
       t@@ -32,6 +32,60 @@ from bitcoin import is_old_seed, is_new_seed
        import version
        
        
       +# http://www.asahi-net.or.jp/~ax2s-kmtn/ref/unicode/e_asia.html
       +CJK_INTERVALS = [
       +    (0x4E00, 0x9FFF, 'CJK Unified Ideographs'),
       +    (0x3400, 0x4DBF, 'CJK Unified Ideographs Extension A'),
       +    (0x20000, 0x2A6DF, 'CJK Unified Ideographs Extension B'),
       +    (0x2A700, 0x2B73F, 'CJK Unified Ideographs Extension C'),
       +    (0x2B740, 0x2B81F, 'CJK Unified Ideographs Extension D'),
       +    (0xF900, 0xFAFF, 'CJK Compatibility Ideographs'),
       +    (0x2F800, 0x2FA1D, 'CJK Compatibility Ideographs Supplement'),
       +    (0x3190, 0x319F , 'Kanbun'),
       +    (0x2E80, 0x2EFF, 'CJK Radicals Supplement'),
       +    (0x2F00, 0x2FDF, 'CJK Radicals'),
       +    (0x31C0, 0x31EF, 'CJK Strokes'),
       +    (0x2FF0, 0x2FFF, 'Ideographic Description Characters'),
       +    (0xE0100, 0xE01EF, 'Variation Selectors Supplement'),
       +    (0x3100, 0x312F, 'Bopomofo'),
       +    (0x31A0, 0x31BF, 'Bopomofo Extended'),
       +    (0xFF00, 0xFFEF, 'Halfwidth and Fullwidth Forms'),
       +    (0x3040, 0x309F, 'Hiragana'),
       +    (0x30A0, 0x30FF, 'Katakana'),
       +    (0x31F0, 0x31FF, 'Katakana Phonetic Extensions'),
       +    (0x1B000, 0x1B0FF, 'Kana Supplement'),
       +    (0xAC00, 0xD7AF, 'Hangul Syllables'),
       +    (0x1100, 0x11FF, 'Hangul Jamo'),
       +    (0xA960, 0xA97F, 'Hangul Jamo Extended A'),
       +    (0xD7B0, 0xD7FF, 'Hangul Jamo Extended B'),
       +    (0x3130, 0x318F, 'Hangul Compatibility Jamo'),
       +    (0xA4D0, 0xA4FF, 'Lisu'),
       +    (0x16F00, 0x16F9F, 'Miao'),
       +    (0xA000, 0xA48F, 'Yi Syllables'),
       +    (0xA490, 0xA4CF, 'Yi Radicals'),
       +]
       +
       +def is_CJK(c):
       +    n = ord(c)
       +    for imin,imax,name in CJK_INTERVALS:
       +        if n>=imin and n<=imax: return True
       +    return False
       +
       +
       +def prepare_seed(seed):
       +    # normalize
       +    seed = unicodedata.normalize('NFKD', unicode(seed))
       +    # lower
       +    seed = seed.lower()
       +    # remove accents
       +    seed = u''.join([c for c in seed if not unicodedata.combining(c)])
       +    # normalize whitespaces
       +    seed = u' '.join(seed.split())
       +    # remove whitespaces between CJK
       +    seed = u''.join([seed[i] for i in range(len(seed)) if not (seed[i] in string.whitespace and is_CJK(seed[i-1]) and is_CJK(seed[i+1]))])
       +    return seed
       +
       +
        filenames = {
            'en':'english.txt',
            'es':'spanish.txt',
       t@@ -63,19 +117,9 @@ class Mnemonic(object):
            @classmethod
            def mnemonic_to_seed(self, mnemonic, passphrase):
                PBKDF2_ROUNDS = 2048
       -        mnemonic = self.prepare_seed(mnemonic)
       +        mnemonic = prepare_seed(mnemonic)
                return pbkdf2.PBKDF2(mnemonic, 'mnemonic' + passphrase, iterations = PBKDF2_ROUNDS, macmodule = hmac, digestmodule = hashlib.sha512).read(64)
        
       -    @classmethod
       -    def prepare_seed(self, seed):
       -        # normalize
       -        seed = unicodedata.normalize('NFKD', unicode(seed))
       -        # lower
       -        seed = seed.lower()
       -        # remove accents and whitespaces
       -        seed = u''.join([c for c in seed if not unicodedata.combining(c) and not c in string.whitespace])
       -        return seed
       -
            def mnemonic_encode(self, i):
                n = len(self.wordlist)
                words = []
       t@@ -120,4 +164,3 @@ class Mnemonic(object):
                        break
                print_error('%d words'%len(seed.split()))
                return seed
       -
   DIR diff --git a/lib/version.py b/lib/version.py
       t@@ -1,6 +1,6 @@
        ELECTRUM_VERSION = "2.0"    # version of the client package
        PROTOCOL_VERSION = '0.9'    # protocol version requested
       -NEW_SEED_VERSION = 9        # electrum versions >= 2.0
       +NEW_SEED_VERSION = 10       # electrum versions >= 2.0
        OLD_SEED_VERSION = 4        # electrum versions < 2.0