문자열 encoding 인코딩과 decoding디코딩




프로그래밍을 할 때 문자 데이터를 처리할 때 인코딩과 디코딩이라는 용어를 많이 사용하고 보게됩니다.

흔히, 한글이 깨지면 encoding 이 어떤 방법으로 되어있는지 체크합니다.


인코딩 encoding 의 원래 의미는 ‘부호화’ 지만 현재는 ‘부호화’ 라는 의미 외에도 ‘부호화 하는 방법’이라는 의미로 쓰이기도 합니다.


먼저 , encoding(부호화) 란 ?

처음에 컴퓨터는 계산(compute)을 하기위해서 만들어진 기기입니다. 

그리고 컴퓨터의 구현 방법상 디지털 방식의 데이터를 받아서 처리하기 때문에 모든 데이터를 bit 로 표현하기 때문에 우리가 일상에서 사용하는 문자들을 컴퓨터를 이용하여 처리하기 위해서는 컴퓨터가 알아들을 수 있는 

bit 형식의 데이터로 변경해주는 작업이 필요한데 이 작업이 바로 encoding(부호화) 입니다.


두 번째로 encoding은 부호화를 하는 방법으로도 쓰이고 있습니다.

개발자들은 문자가 깨져서 나오면 encoding이 머야? 라고 묻는데 이는 부호화하는 방법이 무엇이냐고 묻는 것입니다.\


부호화하는 방법에는 우리가 자주 보는 ascii 코드, utf-8, cp949 등 여러 방법이 있습니다.

Encoding 방식에 따라서 문자를 bit 로 변경하는 방법이나 표현할 수 있는 문자의 범위가 다릅니다.

ascii  코드 같은 경우는 7bit 로 문자들을 표현하고, 한글은 표현할 수 없습니다.

주로 프로그래밍을 할 때는 unicode 방식을 많이 이용하고, 한글은 utf-8 방식으로 인코딩 했을 때 3byte 사이즈로 인코딩됩니다.




당연히 반대로 프로그래밍에서 Decoding 은 부호를 다시 사람들이 알아 볼 수 있는 문자로 바꿔주는 것을 의미합니다.

디코딩은 어떤 방식으로 encoding 했는지에 대한 정보가 필요합니다.

Utf-8로 인코딩하고 cp949로 디코딩하면 흔히 말하는 문자가 깨지는 현상이 발생하게 됩니다. 




간단하게 인코딩과 디코딩에 대해 알아보았습니다.


간단하지만 자주 쓰이는 정보이기 때문에 이번에 명확하게 알고 넘어가면 좋을 것 같습니다.



감사합니다.


리버싱 , 리버스 엔지니어링은 어떤 것을 의미할까요?



인프런에서 어떤 강의가 있나 살펴보던 중에 리버스 엔지니어링에 관한 강의가 있어서 미리보기 수강 후 강의를 들어볼까 고민하고 있습니다...! 미리보기에서 들었던 내용과 평소 가지고 있던 내용을 간단히 정리 및 소개하려고 합니다.




리버싱, 리버스 엔지니어링이란?



리버스라는 영어 단어를 살펴보면 거꾸로, 반대로 라는 의미가 있기 때문에 대략적인 의미를 유추해 볼 수 있습니다.



제가 생각했던 소프트웨어에서 리버싱이란 이미 만들어진 프로그램, 즉 소프트웨어를 분석하여 그 내부를 알아내는 것이라고 평소에 생각하고 있었습니다.



강의해서 소개하는 리버싱이란 의미는 이미 만들어진 소프트웨어를 분석하는 것이라고 소개하고 있습니다.



물리적인 신호가 소프트웨어를 통해 제어가 되면서 자동차도 리버싱이 가능해짐…

자동차의 통신 프로토콜을 분석..!


또, 리버스 엔지니어링(Reverse engineering) 에 대해서는 역설계, 분해 공학( 다른 회사의 상품을 분해하여 그 생산 방식을 알아낸 뒤 복제하는 것) 이라고 말하고 있었습니다.

ex) 예를 들자면, 자동차 또한 전기 신호를 이용하여 작동을 제어하기 때문에 해당 전기 신호를 제어하는 소프트웨어의 통신 규약이나 명령어들을 알아낸다면 영화처럼 차량을 

무선으로 탈취하여 조종할 수 있게 됩니다. 



리버싱이 필요한 이유, 리버싱은 어디에 쓰일 까요 ?

크게 해커, 악성 코드 전문가, 자신의 프로젝트의 보안을 위해서, 심심해서...(가장 무서운 것 같아요.)




소프트웨어 리버싱을 잘 하기 위해서는 무엇을 알아야 할까요?

 자연스럽게 생각해본다면 어떤 기술로 만들어진 결과물을 통해서 어떻게 만들어졌는지 분석하려고 한다면 해당 소프트웨어에 사용한 기술

이나 구조등을 당연히 잘 안다면 큰 도움이 될 수 있습니다. 또한, 어떤 소프트웨어 프로그램이든 해당 운영체제의 맞는 기계어로 변형되어 동

작하기 때문에 기계어를 잘 안다면 기계어를 보고 어떤 기능을 하는 프로그램인지 분석 할 수 있을 것 입니다.


- 강의에서는 리버서에게 필요한 기술 조각이라는 표현으로 리버싱을 위해 필요한 것들을 소개하고 있습니다.

아키텍쳐

기계어

도구 활용 능력

개발 

경험


간단하게 리버싱의 의미와 리버싱이 쓰이는 분야, 리버싱을 잘 하기위해서는 

어떤 기술들을 공부해야하는지에 대해서 정리해봤습니다.

감사합니다.





  1. 이진 2018.05.21 16:01 신고

    온라인용 apk파일을 분해하여 맟춤형으로 해주시면 안될까요?
    사례금은500드릴께요.
    whfflsek11@gmail.com
    입니다...

포인터... 머였더라?





학교 다니면서 C를 교양이든 전공이든 수강한 사람이면 c언어로 무엇을 할 수 있는지는 몰라도 포인터는 기억할 것 이다. 

C언어 하면 포인터하고 포인터하면 C가 떠오른다.


나름 학부 때 C를 공부하면서 포인터, 더블 포인터를 잘 이해했다고 생각했는데 전자공학을 전공하다보니 프로그래밍을 한 동안 쉬고, 바로 파이썬으로 개발을 하니 포인터 가 어떤 변수를 저장해놓은 주소를 가리키는 변수 였던것 같긴한데 정확히 기억이 안나서 다시 한번 자료를 살펴보고 간단한게 글을 남기면서 되새김질 해보려고 한다.

구체적으로 다시 되새김질 하게 된 계기는 파이썬을 공부하면서 파이썬은 객체를 동적으로 선언하는 과정을 보다보면 특히 리스트와 같은 자료구조의 객체를 생각하다보면 자연스럽게 포인터 개념이 나오는데 갑자기 조금 당황하는 나의 모습을 보면서 다시 한 번 살펴봐야겠다는 생각을 하게된다.


먼저 변수의 개념을 살펴보면, 변수는 메모리 공간을 말한다. 


즉, 변수를 선언 하는 것은 RAM의 메모리 공간을 할당하게 된다.

우리가 DB에서 데이터를 꺼내오기 위해 인덱싱을 하듯, 메모리에도 데이터를 구분하기 위해 주소라는 개념이 필요하다.

쉽게 말해, 내가 어떤 수를 RAM의 어떤 주소에 저장했는지 표시해야된다는 의미다.


Python 의 경우에는 컴파일러가 알아서 주소를 할당해주지만 애초에 C언어는 운영체제를 만들기 위해 만들어진 언어기 때문에 직접 주소를 할당해줄 수 있어야한다.


파이썬에서는 하드웨어를 직접 컨트롤(메모리의 주소를 직접 조정하지 않는 것이)하지 않는게 장점이지만, C언어의 장점은 하드웨어를 다루기 쉬운것이 장점이다.   


즉, C언어의 힘은 포인터이고, 포인터가 하드웨어를 다루는데 중요한 역할을 한다.

기본 포인터의 개념

변수 => 메모리 공간

포인터 => 메모리 공간의 주소를 저장하는 변수

 

위 예제를 살펴보면 b 는 변수(메모리 공간을 할당) , a에 b의 메모리 주소를 할당했다.


위 예제는 메모리 주소로 메모리 공간의 저장되어 있는 데이터를 변경했다.

주소도 변경할 수 있을까? 물론 가능하다. 포인터 즉 메모리 변수도 변수이기 때문에 어딘가의 메모리에 저장되기 때문에 메모리 주소가 있고, 이 개념이 더블 포인터이다.



더블 포인터로 메모리에 있는 데이터에 접근해서 값을 변경도 가능하다. 


간단하게 C 언어의 포인터 개념을 복습해봤다…! 다음에 시간이 나는 대로 C언어로 간단한 프로젝트를 구현해봐야겠다..! 








객체 지향 프로그래밍이란 무엇이고, 어떻게 사용되고 있는지 정리해보겠습니다.



먼저, 객체 지향 프로그래밍이란?


위키백과의 정의와 관련 내용을 살펴보면


프로그래밍의 설계 방법으로 객체라는 것을 만들고 이들을 통해 프로그래밍 하는 방법이라고 할 수 있습니다.


객체 지향 프로그래밍에서는 객체가 멤버 함수를 가지는 것 과 같이 '객체' 라는 단위가 중심이 됩니다.



이 객체 지향 프로그래밍에서 이용되는 개념인


class, object , encapsulation, inheritance, polymorphism, abstract 를 하나하나 살펴 보겠습니다.


  • 정의

객체 지향 프로그래밍(Object-Oriented Programming), 줄여서 OOP.

프로그램을 어떻게 설계해야 하는지에 대한 일종의 개념이자 방법론.

  • 상세 절차

프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수많은 '객체'라는 기본 단위로 나누고 이 객체들의 상호작용으로 서술하는 방식이다.

  • 절차적 프로그래밍과 비교

기존 절차적 프로그래밍에서는 함수를(메소드) 기계, 데이터를 원료로 생각해서 데이터가 함수 사이를 통과하면서 차츰 순서대로 가공돼 나가는 방식으로 이해한다면 객체 지향 프로그래밍에서는 데이터를 중심으로 메서드가 데이터에 접근해서 수정한다는 개념이다. 즉 원료가 움직이냐 기계(함수{메소드})가 움직이냐의 차이.

출처 : 위키백과 

https://namu.wiki/w/%EA%B0%9D%EC%B2%B4%20%EC%A7%80%ED%96%A5%20%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D




1. Class


class 는 object의 template이라고 할 수 있습니다.


class 는 쉽게 말해서 한 번 정의를 해 놓고 그 성질(데이터, 메서드) 를 갖는 객체를 생성하는데 쓰입니다.


예를 들어,  Person이라는 class를 만들게 되면 해당 클래스의 성질을 갖는 인스턴스를 생성할 수 있습니다.


in python 


class Person:

def init(self, height, weight, language):

self.height = height

self.weight = weight

self.language = language


def run(self):

print('run!')




2. Object


Object는 클래스의 instance 입니다.


클래스의 instance인 Object를 생성하면 컴퓨터의 메모리에 올라가게 되고, Object를 사용할 수 있게 됩니다.




3. encapsulation


클래스의 변수나 메서드를 묶는 것을 캡슐화 , encapsulation 이라고 합니다.


java에서의 경우 접근지정자(public , protected, private) 을 통해 인스턴스들의 접근을 제어 할 수 있습니다.







4. Inheritance


다음은 상속입니다.


상속은 부모/자식 개념으로 위에 살펴본 예제인 Person이라는 클래스가 있을 때 Player( 운동선수)라는 클래스를 만들 때


사람 class인 person을 상속 받아서 코드의 재사용성을 높일 수 있습니다.


class Player(Person):


bla bla~




5. polymorphism 


다음은 다형성입니다. 같은 형태를 가졌지만 다르게 동작하는 성질을 말합니다.


polymorphism 에는 Overriding 과 Overloading 이 있습니다.



Overriding의 경우는 부모에게 상속 받은 멤버함수나 속성을 자식 클래스에게 변경하는 것을 말합니다.



class Person:

def init(self, height, weight, language):

self.height = height

self.weight = weight

self.language = language


def run(self):

print('run!')


class Player(Person):

def run(self):

print('run!!!!!!!!!!!!')


다음과 같이 run() 이라는 같은 함수의 이름이지만 다르게 동작합니다.


Overloading의 경우는 python에서는 존재하지 않고 java에서 존재하는 개념으로 같은 함수의 argument(인자)의 갯수가 다른 경우를 의미합니다.





6. Abstraction (추상화)


마지막 추상 클래스 개념입니다.


아키텍쳐를 설계하는 엔지니어의 경우 개발을 직접하지 않고 추상화 클래스를 생성하여 개발자에게 전달할 수 있습니다.


public abstract class Car {

public abstract void run();

public abstract voud accelerate():

}


아키텍쳐 엔지니어가 이런식으로 추상화하여 개발자에게 전달하면 개발자가 이를 구현할 때 사용할 수 있습니다.





이것으로 OOP에 대한 개념을 살펴봤습니다.


감사합니다.






POSIX 스레드란 ? Pthread ?


gevent 공부하던 중에 gevent 주된 패턴인 Greenlet 공부하게 됐고, Greenlet C확장 모듈 형태로 제공되는 경량 코루틴(Coroutine) 이고 운영체제에 의해 스케쥴링되는 process들과 POSIX 쓰레드들을 사용하여 병렬처리한다는 내용을 알게 됐습니다.


POSIX 스레드는 스레드들을 병렬적으로 처리할 있도록 돕는 것이라고 생각하고 넘겼다가, 제대로 뭔지 알고 넘어가야겠다는 생각이들어서 정리하게 됐다.



결론 부터 말하면 Posix 스레드는 스레드들이 병렬적으로 수행될 수 있도록 스레드를 새로 만들고 또 스케쥴링하는 api 입니다.





자세하게 살펴보기위해 , 위키백과에서 정의를 살펴보면


POSIX 스레드란 ? 


POSIX 스레드(POSIX Threads, 약어PThread) 병렬적으로 작동하는 소프트웨어의 작성을 위해서 제공되는 표준 API.

Pthread 모든 유닉스 계열 POSIX 시스템에서, 일반적으로 이용되는 라이브러리이다. 유닉스 계열 운영 체제라 하면 리눅스솔라리스 등이 포함된다. Unix 시스템과는 다른 길을 걷고 있는 Windows 역시 여러가지 이유로 Pthread 지원한다. 예를 들어 pthread-w32 이용하면 윈도 상에서도 Pthread API subset 함수를 이용할 있다. pthread-w32  redhat.com 에서 얻을 있다. (Pthread 에서 P 항상 대문자로 쓰도록 약속되어 있다.)




POSIX 스레드(POSIX Threads, 약어: PThread) 병렬적으로 작동하는 소프트웨어의 작성을 위해서 제공되는 표준 API.


간단하게 말하면 POSIX THREAD 이용해서 새로운 스레들을 만들고, 스케쥴링하고 병렬적으로 처리할 있도록 돕는 API라고 생각할 있다.




실제로 pthread를 통해 스레드 생성, 스레드 종료, 스레드 동기화를 위한 api 제공합니다.










커널이란?



커널은 운영 체제의 핵심 부분으로, 커널의 역할 역시 운영 체제의 핵심 역할이라 있다


애플리케이션들과 하드웨어를 연결하는 인터페이스를 제공한다고 있다.



linux 예로 들면


Shell application이라고 하면 shell에서 명령어를 하면 커널에서 스케쥴링 하고 명령어에 필요한 하드웨어들을 사용할 있도록 연결해준다라고 생각할 있을 같다.


위키백과에서 커널의 역할과 종류에 대해 아주 설명되어 있다.



출처: 위키백과

링크: https://ko.wikipedia.org/wiki/%EC%BB%A4%EB%84%90_(%EC%BB%B4%ED%93%A8%ED%8C%85



커널의 역할


  • 보안

커널은 컴퓨터 하드웨어와 프로세스의 보안을 책임진다.


  • 자원 관리

한정된 시스템 자원을 효율적으로 관리하여 프로그램의 실행을 원활하게 한다. 특히 프로세스에 CPU 할당하는 스케쥴링을 한다.


  • 추상화

같은 종류의 부품에 대해 다양한 하드웨어를 설계할 있기 때문에 하드웨어에 직접 접근하는 것은 문제를 매우 복잡하게 만들 있다

일반적으로 커널은 운영 체제의 복잡한 내부를 감추고 깔끔하고 일관성 있는 인터페이스를 하드웨어에 제공하기 위해 가지 하드웨어 추상화들로 구현된다. 하드웨어 추상화는 프로그래머가 여러 장비에서 작동하는 프로그램을 개발하는 것을 돕는다

하드웨어 추상화 계층 (HAL) 제조사의 장비 규격에 대한 특정한 명령어를 제공하는 소프트웨어 드라이버에 의지한다.











컴파일러와 인터프리터 분명 많이 들어봤고 책에서 정의도 봤지만 


   어느 순간 보면 정확하게 의미를 모르고 있는 저의 모습을 볼 수 있었습니다.




컴파일러와 인터프리터


고급언어로 작성된 프로그램을 실행하는 데에는 두가지 방법이 있다.


바로, 컴파일러와 인터프리터이다. 컴파일러와 인터프리터는 모두 고급언어(java, c,  python) computer 읽을 있는 언어(2진수)


환하는 장치이다.


컴파일러와 인터프리터를 가장 비유한 표현은 알려져있다시피, 번역과 통역이다. 컴파일은 번역과 같이 전체를 번역 의미를 전달한다.  인터프리터는 한마디 한마디를 통역해주듯이 코드를 해석해서 바로 실행시켜준다. 



인터프리터는 고급언어로 작성된 소스코드 명령문들을 번에 줄씩 읽어들여서 실행하는 프로그램으로, 고급 명령어들을 기계어가 아닌 중간 형태로 변환한 다음 실행을 시킨다. 반면에 컴파일러는 특정 프로그램 언어로 작성된 문장을 처리하여 직접 기계어로 변환시켜준다.


결국, 컴파일러와 인터프리터의 가장 차이점은 변환을 번에 하느냐 아니면 부분적으로 해석하고 실행을 하느냐 라고 있을 같다.



인터프리터 언어에 조금 자세히 살펴보면 다음의 3가지 기능 중에 적어도 가지 기능을 가진 프로그램이다.

  1. 소스코드를 직접 실행한다.
  2. 소스코드를 효율적인 다른 중간 코드로 변환하고, 변환한 것을 바로 실행한다.
  3. 인터프리터 시스템의 일부인 컴파일러가 만든, 미리 컴파일된 저장 코드의 실행을 호출한다.



- 컴파일러의 실행과정 
    1) 어휘분석(Lexical Analysis)
    2) 구분 분석(Parsing) 
    3) 의미분석(Semantics Analysis) 
    4) 중간 코드 생성
    5) 기계어 코드 생성


- 인터프리터의 프로그램 실행 과정
    1)
한명령어를 메모리에서 가져온다
    2)
가져온 명령어를 해석한다
    3)
필요한 데이터를 가져온다
    4)
명령을 실행한다.





컴파일러


장점

  • 전체 프로그램 실행속도가 빠르다. (한 번 실행파일을 만들어 놓으면, 다음부터는 빠르게 실행시킬 수 있다.)

단점

  • 전체 프로그램을 번에 변환함으로 메모리를 번에 많이 사용.
  • 일부분을 수정하는 경우도 전체 코드를 다시 컴파일 해야 하기 때문에 시간이 소요된다.


인터프리터


장점

  - 실행코드를 변환하여 실행함으로써 메모리를 적게 사용한다. 

  • 부분을 수정하는 경우 수정 빠르게 확인할 있다.

단점

  • 전체 프로그램 실행시간이 오래 걸린다.


- 참고한 자료



- 아직 풀리지 않은 의문.


CPU 도 하나의 인터프리터 라고 알고 있는데 결국에는 기계어로 변환 후에 연산을 수행할 것 같은데 


파이썬과 같은 인터프리터 언어에서 소스코드를 직접 수행하거나, 중간 형태로 바꿔서 실행할 때도 결국에는 기계어로 변환 후에 수행이 되어지는 것이 아닌지?


그리고, 실행한다는 것의 의미는 결국 소스코드가 버스를 통해서 cpu에서 수행이 되어진다는 의미인데 결국 (컴파일러 언어)기계어로 변환해서 cpu의 캐시 메모리로 가는 것 과 (인


터프리터 언어) 기계어로 변환하지 않은상태로 캐시 메모리로 가는 것가?






  1. 얼또 2017.11.01 17:30 신고

    응원합니다



코딩을 하다보면 



'멀티프로세스'와 '멀티스레드' 란 단어를 많이 듣습니다.


저도 크롤링을 할 때 



python multiproessing 모듈을 이용해서 크롤링 한 경험이 있습니다.



먼저, 스레드와 프로세스의 정의를 확인해 봤습니다.


운영체제가 시스템의 자원을 어떤 단위로 할당하고, 프로세스와 스레드가 이를 어떻게 사용 하는가를 알고 있어야 합니다.



- 프로세스 (Process)


프로세스는 실행될 때 운영체제에게 독립적인 주소공간, 메모리 등 자원(파일, 데이터, 프로세서의 상태, 메모리 영역 주소 공간, 


스레드정보, 전역데이터등)을 할당받습니다.


즉, 하나의 실행되고 있는 프로그램이라고 할 수 있습니다.


제가 Pycharm을 실행시키면 운영체제는 Pycharm 프로세스에게 자원을 할당하여 독립적으로 수행할 수 있도록 합니다.


독립적이기 때문에 서로 다른 프로세스 끼리는 자원을 공유 할 수 없습니다.




- 스레드 (Thread)


하나의 프로그램 내에서 여러개의 실행 흐름을 두기 위한 모델.


하나의 프로세서(프로그램) 에서 각 독립적인 일의 단위인 스레드로 여러 작업을 처리할 수 있다. 


하나의 프로세서가 병렬적으로 여러개의 작업을 수행하기 위해서는 작업들을 스레드화하여 멀티스레딩이 가능하게 해야한다.



- 프로세스와 스레드의 차이점


자원의 관점에서 스레드는 해당 스레드를 위한 스택을 생성할 뿐 프로세스 안에서 그 이외의 Code, Data, Heap 영역을 공유한다.


프로세스는 독립적인 자원을 받기 때문에 메모리 영역(code, data, heap , stack) 을 다른 프로세스들과 공유하지 않는다.



텍스트 : pc (pc counter)


데이터: 글로벌 변수, static 변수 저장


힙 : 메모리 관리, 동적 메모리 할당 (시스템 콜로 관리)


스택: 임시 데이터 저장 - 로컬 변수, 리턴 어드레스



- 멀티 프로세스의 문제점


 - context switching 이 느리다. (독립된 두 개의 프로그램 실행을 위해서 context switching이 일어나는데 이


과정이 멀티 쓰레드보다 느리다. 멀티쓰레드는 공유하는 자원이 있기 때문에 레지스터에 상대적으로 적은 양의


정보들을 넣는다.)


- 프로세스 사이에서 공유하는 메모리가 하나도 없기 때문에 컨텍스트 스위칭이 발생하면 캐쉬에 있는 모든 데이터를


모두 지우고 다시 캐쉬정보를 불러오기 때문에 속도가 느릴수 밖에 없다.





+ Recent posts