Количество байтов в textarea с использованием javascript

Мне нужно подсчитать, сколько времени в байтах текстовое поле, когда UTF8 кодируется с помощью javascript. Любая идея, как я это сделаю?

спасибо!

Ответы

Ответ 1

edit: как указал Didier-l, эта функция не учитывает суррогатные символы.

Ответ broofa должен правильно считать суррогаты, см. fooobar.com/questions/339586/....

Я тестировал две предложенные версии здесь, а также наивную реализацию:

 getUTF8Length: function(string) {
    var utf8length = 0;
    for (var n = 0; n < string.length; n++) {
        var c = string.charCodeAt(n);
        if (c < 128) {
            utf8length++;
        }
        else if((c > 127) && (c < 2048)) {
            utf8length = utf8length+2;
        }
        else {
            utf8length = utf8length+3;
        }
    }
    return utf8length;
 }

В результате моя версия немного быстрее в firefox и значительно быстрее в хром (~ 30x), чем в опубликованных версиях.

Ответ 2

encodeURIComponent(text).replace(/%[A-F\d]{2}/g, 'U').length

Ответ 3

Если у вас есть символы non-bmp в вашей строке, это немного сложнее...

Поскольку javascript кодирует UTF-16, а "символ" - это 2-байтовый (16 бит), все многобайтовые символы (3 и более байтов) не будут работать:

    <script type="text/javascript">
        var nonBmpString = "foo€";
        console.log( nonBmpString.length );
        // will output 5
    </script>

Символ "€" имеет длину 3 байта (24 бит). Javascript интерпретирует его как 2 символа, потому что в JS символ является 16-битным блоком.

Итак, чтобы правильно получить байтес смешанной строки, мы должны закодировать нашу собственную функцию fixedCharCodeAt();

    function fixedCharCodeAt(str, idx) {
        idx = idx || 0;
        var code = str.charCodeAt(idx);
        var hi, low;
        if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
            hi = code;
            low = str.charCodeAt(idx + 1);
            if (isNaN(low)) {
                throw 'Kein gültiges Schriftzeichen oder Speicherfehler!';
            }
            return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
        }
        if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
            // We return false to allow loops to skip this iteration since should have already handled high surrogate above in the previous iteration
            return false;
            /*hi = str.charCodeAt(idx-1);
            low = code;
            return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;*/
        }
        return code;
    }

Теперь мы можем подсчитать байты...

    function countUtf8(str) {
        var result = 0;
        for (var n = 0; n < str.length; n++) {
            var charCode = fixedCharCodeAt(str, n);
            if (typeof charCode === "number") {
                if (charCode < 128) {
                    result = result + 1;
                } else if (charCode < 2048) {
                    result = result + 2;
                } else if (charCode < 65536) {
                    result = result + 3;
                } else if (charCode < 2097152) {
                    result = result + 4;
                } else if (charCode < 67108864) {
                    result = result + 5;
                } else {
                    result = result + 6;
                }
            }
        }
        return result;
    }

Кстати... Вы не должны использовать метод encodeURI, потому что он является собственной функцией браузера;)

Больше вещей:


Приветствия

frankneff.ch / @frank_neff

Ответ 4

Объединяя различные ответы, следующий метод должен быть быстрым и точным и избегать проблем с недействительными суррогатными парами, которые могут вызвать ошибки в encodeURIComponent():

function getUTF8Length(s) {
  var len = 0;
  for (var i = 0; i < s.length; i++) {
    var code = s.charCodeAt(i);
    if (code <= 0x7f) {
      len += 1;
    } else if (code <= 0x7ff) {
      len += 2;
    } else if (code >= 0xd800 && code <= 0xdfff) {
      // Surrogate pair: These take 4 bytes in UTF-8 and 2 chars in UCS-2
      // (Assume next char is the other [valid] half and just skip it)
      len += 4; i++;
    } else if (code < 0xffff) {
      len += 3;
    } else {
      len += 4;
    }
  }
  return len;
}

Ответ 5

Добавить функцию подсчета длины байта в строку

String.prototype.Blength = function() {
    var arr = this.match(/[^\x00-\xff]/ig);
    return  arr == null ? this.length : this.length + arr.length;
}

то вы можете использовать .Blength(), чтобы получить размер

Ответ 6

Как насчет простого:

unescape(encodeURIComponent(utf8text)).length

Фокус в том, что encodeURIComponent, похоже, работает с символами, а unescape работает с байтами.

Ответ 7

Я спрашивал себя то же самое. Это лучший ответ, который я наткнулся на:

http://www.inter-locale.com/demos/countBytes.html

Вот фрагмент кода:

<script type="text/javascript">
 function checkLength() {
    var countMe = document.getElementById("someText").value
    var escapedStr = encodeURI(countMe)
    if (escapedStr.indexOf("%") != -1) {
        var count = escapedStr.split("%").length - 1
        if (count == 0) count++  //perverse case; can't happen with real UTF-8
        var tmp = escapedStr.length - (count * 3)
        count = count + tmp
    } else {
        count = escapedStr.length
    }
    alert(escapedStr + ": size is " + count)
 }

но ссылка содержит живой пример ее воспроизведения. "encodeURI (STRING)" - это строительный блок здесь, но также посмотрите на encodeURIComponent (STRING) (как уже указано в предыдущем ответе), чтобы узнать, какой из них соответствует вашим потребностям.

Привет

Ответ 8

encodeURI(text).split(/%..|./).length - 1

Ответ 9

установите meta UTF-8 как раз и это ОК!

<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html;charset=utf-8">

и js:

if($mytext.length > 10){
 // its okkk :)
}

Ответ 10

Попробуйте следующее:

function b(c) {
     var n=0;
     for (i=0;i<c.length;i++) {
           p = c.charCodeAt(i);
           if (p<128) {
                 n++;
           } else if (p<2048) {
                 n+=2;
           } else {
                 n+=3;
           }
      }return n;
}