회사에서 프로젝트를 진행하면서 글자 수 관련 이슈가 나왓다 처음에는 글자수를 length()
함수를 사용해 길이만 체크하면 된다고 생각했지만, DB에 해당 부분을 넣을 때 byte를 정해 놓는데, 영어 와 다르게 한글은 encoding 방법에 따라 byte수가 변경이 된다 euc-kr
2byte utf-8
3byte 이런 byte문제 때문에 그냥 넣었더가는 db에서 오류가 나는 이슈가 존재했다.
코드로 일단 확인해보자
// Function
const getByteLengthOfString = function(s,b,i,c){
for(b=i=0;c=s.charCodeAt(i++);b+=c>>11?3:c>>7?2:1);
return b;
};
// Test
const test = '테스트';
console.log('length : ', getByteLengthOfString(test), 'Bytes');
결과) length : 9 Bytes
코드가 이해가 안되는 부분이 있어서 적으면서 이해해보자.
1. getByteLengthOfString
함수의 첫 반복문을 보면 b=i=0
이다. b와 i는 0이다.
s 는 받을 문자열이다. chartCodeAt
함수는 문자열의 인덱스에 대한 UTF-16
코드로 변경해주는 함수이다. 그 다음에 b+=c>>11?3:c>>7?2:1
이부분 삼항 연산자를 많이 쓴거 같은 느낌인데 c>>11
이면 3을 넣고 아니면 c>>7
이 참이면 2 이고 아니면 1을 더한다.
c>>11 이 뭐지?
right shift비트 연산자라는 것을 알수 있었다! 32bit 부호에서 다 왼쪽으로 붙이고 그 앞에 0을 붙인다는데,, >>
는 쉽게 이야기해서 211 의 수를 나누라는 것! 반대의 경우는 <<
211을 곱하라는 것!
// Function
String.prototype.getBytes = function() {
const contents = this;
let str_character;
let int_char_count = 0;
let int_contents_length = contents.length;
for (k = 0; k < int_contents_length; k++) {
str_character = contents.charAt(k);
if (escape(str_character).length > 4)
int_char_count += 2;
else
int_char_count++;
}
return int_char_count;
}
// Test
const test = '테스트';
console.log('length : ', test.getBytes(), 'Bytes');
결과) length : 6 Bytes
escape
이 뭐지?
알파벳과 숫자 및 * , @, - , _ , + , . , / 를 제외한 문자를 모두 16진수 문자로 바꾸어 줍니다
// Function
String.prototype.getStringFromByteLength = function( length ) {
const contents = this;
let str_character;
let int_char_count = 0;
let int_contents_length = contents.length;
let returnValue = '';
for (k = 0; k < int_contents_length; k++) {
str_character = contents.charAt(k);
if (escape(str_character).length > 4)
int_char_count += 2;
else
int_char_count++;
if ( int_char_count > length ) {
break;
}
returnValue += str_character;
}
return returnValue;
}
// Test
const test = '테스트';
console.log('result : ', test.getStringFromByteLength(4));
결과) result : 테스
4byte까지만 입력하게 해서 테스 까지만 나오게 되었다.
제 댓글의 바이트는 몇일까요?