기본 콘텐츠로 건너뛰기

벡터와 행렬에 관련된 그림들

ASCII 코드

ascii는 정수와 문자 등을 연결해 주는 규약으로 그 구성 요소들은 표 1과 같습니다.

ASCII 코드의 구성
구성요소코드 포인트
영문 소문자 a ~ z65 ~ 90
영문 대문자 A~z97 ~ 122
구두점, 기호, 공백 $, ! , " "등32 ~ 64
자소(graphemes)[, \등91 ~ 96
자소(graphemes){, |123 ~ 126
인쇄할 수 없는 문자\b 등127

문자 인코딩(character encoding)은 다음과 같이 정의할 수 있습니다.

  • 문자, 구두점, 기호, 공백, 제어문자 등을 정수로, 궁극적으로 비트(bit)로 변환하는 방법
  • 각 문자는 고유한 비트 시퀀스로 인코딩될 수 있음
  • 문자 등을 정수로 변환한 결과를 코드 포인트(code point)라고 합니다.

ASCII 코드는 총 128개로 구성되어 있으며 파이썬의 내장함수 ord()chr()로 확인할 수 있습니다.

  • ord(문자): 대응하는 정수를 반환
  • chr(숫자): 대응하는 문자를 반환
chr(33)
'!'
ord('!')
33
x=ord('a')
print(x, chr(x))
97 a

모듈 string은 ASCII의 문자집합에 포함된 문자(열)를 다루고 있습니다. 이 모듈에 포함된 문자는 다음의 속성(attribute)으로 확인할 수 있습니다.

import string
string.whitespace
' \t\n\r\x0b\x0c'
string.ascii_letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

위의 속성은 .ascii_lowercase(소문자)와 .ascii_uppercase(대문자)를 함께 반환합니다.

string.digits #10진수 수
'0123456789'
string.hexdigits#16진수 수
'0123456789abcdefABCDEF'
string.octdigits#8진수 수 
'01234567'
string.punctuation
'!"#$%&'()*+,-./:;<=> @[\]^_`{|}~'
string.printable #인쇄할 수 있는 문자들
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=> @[\]^_`{|}~'

비트(bit)는 컴퓨터의 가장 기본적인 정보 단위로 두가지의 가능한 상태만을 나타내는 신호입니다. 숫자로 0과 1로 나타내지만 다음과 같은 의미를 가집니다.

  • 0, 1
  • 'yes', 'no'
  • 'True', 'False'
  • 'on', 'off

아스키 문자의 코드 포인트는 정수 정확히는 십진수입니다. 컴퓨터는 이진수로 인식합니다. 그 결과는 내장함수인 bin()에 의해 확인할 수 있습니다.

x=ord('p')
bin(x)
'0b1110000'

위와 같이 문자를 2진수로 코드화하는 것을 인코딩(encoding)이라하며 반대로 그 코드포인트를 문자로 전환하는 과정을 디코딩(decoding)이라 합니다.

C 등의 언어에서는 어떠한 자료를 입력할 경우 그 자료형을 미리 선언하는데 반해 파이썬은 작은 따옴표(' ')나 큰 따옴표(" ")로 문자임을 선언합니다.

다음은 문자 'c'에 매칭되는 정수와 이를 이진수로 나타낸 것입니다.

ch='c'
ord(ch)
99
bin(ord(ch))
'0b1100011'

다음은 문자를 이진수 즉 비트로 변환하는 함수를 작성해 봅니다. 이 함수에는 .isascii()와 .join() 메소드를 적용한 것입니다.

  • .isascii(): 전달되는 객체가 ascii로 인쇄가능한지를 판단
  • .join(): 전달하는 객체와 연결

다음 함수의 f"{ord(i): 08b}"은 10진수를 8자리의 2진수로 변환한다는 것을 의미합니다. (참조)

def asci2bit(x):
    if not x.isascii():
        raise ValueError("ascii만 전환할 수 있습니다.")
    return("".join(f"{ord(i): 08b}" for i in x))
asci2bit('bits')
' 1100010 1101001 1110100 1110011'
asci2bit('파이썬')
~~ ValueError: ascii만 전환할 수 있습니다.
asci2bit('Start Python. good luck!')
' 1010011 1110100 1100001 1110010 1110100 0100000 1010000 1111001 1110100 1101000 1101111 1101110 0101110 0100000 1100111 1101111 1101111 1100100 0100000 1101100 1110101 1100011 1101011 0100001'

비트로 표현이 가능한 값의 수는 2n개 입니다. 그러므로 사용하는 비트 수에 대해 표현할 수 있는 값의 수는 다음과 같습니다.

for i in [1, 16, 32, 64]:
    print(f'{i} 비트 사용: {2**i} 표현이 가능')
1 비트 사용: 2 표현이 가능
16 비트 사용: 65536 표현이 가능
32 비트 사용: 4294967296 표현이 가능
64 비트 사용: 18446744073709551616 표현이 가능

위의 계산을 역으로 하면 표현에 대한 사용할 비트수를 계산할 수 있습니다.

$$n=\frac{x}{\log(2)}$$
import numpy as np
def needBit(expr):
    return(int(np.log(expr)/np.log(2)))

ascii의 경우 모두 128개의 표현을 가집니다. 그러므로 7비트가 필요합니다. 그러나 컴퓨터는 기본 단위로 7비트 대신 8비트(1바이트)를 사용하기 때문에 ascii 코드로 모든 비트를 채우지 못합니다.

 needBit(128)
7

ascii는 영어외에 다른 언어를 포함하지 않기 때문에 현재는 더 큰 문자를 포함하는 unicode나 UTF-8을 사용합니다. 유니코드는 1,114,112의 가능한 코드 포인트를 포함합니다. ascii코드는 유니코드의 부분집합이면 인쇄가능하지 않는 대부분의 문자를 포함합니다. 그러나 엄격히 말해 유티코드는 인코딩이 아니고 각 문자에 대응하는 기호를 한 쌍으로 하는 맵형식으로 구성되어 있습니다. 이것은 유니코드가 필요한 비트수를 정확히 제시하지 않은 다는 문제를 발생합니다. 이에 비해 UTF-8은 인코딩과 디코딩을 기법을 정확하게 사용할 수 있습니다.

파이썬에서는 .encode().decode() 내장 메서드를 사용하여 인코딩과 디코딩을 실행할 수 있습니다. 즉, .encode()를 사용하여 사람이 읽을 수 있는 문자열을 이진 데이터 또는 원시 비트열로 표시합니다. 반대로 이진 데이터를 읽을 수 있는 문자열로의 전환은 .decode() 메서드로 실행됩니다. 이 메서드의 매개변수 중에 변환을 위한 코드의 종류를 지정하여야 합니다. 사용되는 코드는 utf-8, utf-16, euc-kr, ascii가 있으며 utf-8이 기본값입니다. 영어의 경우 encode() 결과 역시 영어로 반환되지만 다른 언어나 기호는 이진 데이터(16진수 표현)을 반환합니다.

원시 데이터(raw data)를 리터럴(literal)이라고 합니다.

x='coffee'
y='커피' 
x.encode()
b'coffee'
y1=y.encode(); y1
b'커피'

위 결과는 16진수 표현입니다. 이를 이진을 표현하면 다음과 같습니다.

' '.join(f'{i: 08b}' for i in y1)
' 11101100  10111011  10100100  11101101  10010100  10111100'
y1.decode()
'커피'

내장함수 bytes()는 문자에 대응하는 이진 리터럴을 16진 표현으로 반환합니다.

bytes(x, encoding="utf-8")
b'coffee'
bytes(y, encoding="utf-8")
b'\xec\xbb\xa4\xed\x94\xbc

댓글

이 블로그의 인기 게시물

[Linear Algebra] 유사변환(Similarity transformation)

유사변환(Similarity transformation) n×n 차원의 정방 행렬 A, B 그리고 가역 행렬 P 사이에 식 1의 관계가 성립하면 행렬 A와 B는 유사행렬(similarity matrix)이 되며 행렬 A를 가역행렬 P와 B로 분해하는 것을 유사 변환(similarity transformation) 이라고 합니다. $$\tag{1} A = PBP^{-1} \Leftrightarrow P^{-1}AP = B $$ 식 2는 식 1의 양변에 B의 고유값을 고려한 것입니다. \begin{align}\tag{식 2} B - \lambda I &= P^{-1}AP – \lambda P^{-1}P\\ &= P^{-1}(AP – \lambda P)\\ &= P^{-1}(A - \lambda I)P \end{align} 식 2의 행렬식은 식 3과 같이 정리됩니다. \begin{align} &\begin{aligned}\textsf{det}(B - \lambda I ) & = \textsf{det}(P^{-1}(AP – \lambda P))\\ &= \textsf{det}(P^{-1}) \textsf{det}((A – \lambda I)) \textsf{det}(P)\\ &= \textsf{det}(P^{-1}) \textsf{det}(P) \textsf{det}((A – \lambda I))\\ &= \textsf{det}(A – \lambda I)\end{aligned}\\ &\begin{aligned}\because \; \textsf{det}(P^{-1}) \textsf{det}(P) &= \textsf{det}(P^{-1}P)\\ &= \textsf{det}(I)\end{aligned}\end{align} 유사행렬의 특성 유사행렬인 두 정방행렬 A와 B는 'A ~ B' 와 같...

[sympy] Sympy객체의 표현을 위한 함수들

Sympy객체의 표현을 위한 함수들 General simplify(x): 식 x(sympy 객체)를 간단히 정리 합니다. import numpy as np from sympy import * x=symbols("x") a=sin(x)**2+cos(x)**2 a $\sin^{2}{\left(x \right)} + \cos^{2}{\left(x \right)}$ simplify(a) 1 simplify(b) $\frac{x^{3} + x^{2} - x - 1}{x^{2} + 2 x + 1}$ simplify(b) x - 1 c=gamma(x)/gamma(x-2) c $\frac{\Gamma\left(x\right)}{\Gamma\left(x - 2\right)}$ simplify(c) $\displaystyle \left(x - 2\right) \left(x - 1\right)$ 위의 예들 중 객체 c의 감마함수(gamma(x))는 확률분포 등 여러 부분에서 사용되는 표현식으로 다음과 같이 정의 됩니다. 감마함수는 음이 아닌 정수를 제외한 모든 수에서 정의됩니다. 식 1과 같이 자연수에서 감마함수는 factorial(!), 부동소수(양의 실수)인 경우 적분을 적용하여 계산합니다. $$\tag{식 1}\Gamma(n) =\begin{cases}(n-1)!& n:\text{자연수}\\\int^\infty_0x^{n-1}e^{-x}\,dx& n:\text{부동소수}\end{cases}$$ x=symbols('x') gamma(x).subs(x,4) $\displaystyle 6$ factorial 계산은 math.factorial() 함수를 사용할 수 있습니다. import math math.factorial(3) 6 a=gamma(x).subs(x,4.5) a.evalf(3) 11.6 simpilfy() 함수의 알고리즘은 식에서 공통사항을 찾아 정리하...

sympy.solvers로 방정식해 구하기

sympy.solvers로 방정식해 구하기 대수 방정식을 해를 계산하기 위해 다음 함수를 사용합니다. sympy.solvers.solve(f, *symbols, **flags) f=0, 즉 동차방정식에 대해 지정한 변수의 해를 계산 f : 식 또는 함수 symbols: 식의 해를 계산하기 위한 변수, 변수가 하나인 경우는 생략가능(자동으로 인식) flags: 계산 또는 결과의 방식을 지정하기 위한 인수들 dict=True: {x:3, y:1}같이 사전형식, 기본값 = False set=True :{(x,3),(y,1)}같이 집합형식, 기본값 = False ratioal=True : 실수를 유리수로 반환, 기본값 = False positive=True: 해들 중에 양수만을 반환, 기본값 = False 예 $x^2=1$의 해를 결정합니다. solve() 함수에 적용하기 위해서는 다음과 같이 식의 한쪽이 0이 되는 형태인 동차식으로 구성되어야 합니다. $$x^2-1=0$$ import numpy as np from sympy import * x = symbols('x') solve(x**2-1, x) [-1, 1] 위 식은 계산 과정은 다음과 같습니다. $$\begin{aligned}x^2-1=0 \rightarrow (x+1)(x-1)=0 \\ x=1 \; \text{or}\; -1\end{aligned}$$ 예 $x^4=1$의 해를 결정합니다. solve() 함수의 인수 set=True를 지정하였으므로 결과는 집합(set)형으로 반환됩니다. eq=x**4-1 solve(eq, set=True) ([x], {(-1,), (-I,), (1,), (I,)}) 위의 경우 I는 복소수입니다.즉 위 결과의 과정은 다음과 같습니다. $$x^4-1=(x^2+1)(x+1)(x-1)=0 \rightarrow x=\pm \sqrt{-1}, \; \pm 1=\pm i,\; \pm1$$ 실수...