[컴] RabbitMQ 를 이용해서 message 보내고 받기

메시지 송신 수신 / 큐 / 메시지 보내는 법 래빗mq 사용법 엠큐 /


RabbitMQ 를 이용해서 message 보내고 받기

def createTestReceiveQueue():
    parameters = pika.URLParameters(
        "amqp://guest:guest@127.0.0.1/%2F"
    )
    connection = pika.BlockingConnection(parameters)
    channel = connection.channel()
    result = channel.queue_declare(queue='my_q')
    channel.exchange_declare(exchange='my_ex',
                            exchange_type='direct')
    channel.queue_bind(queue='my_q',
                        exchange='my_ex',
                        routing_key='my_rk')


def send():
    parameters = pika.URLParameters(
        "amqp://guest:guest@127.0.0.1/%2F"
    )
    connection = pika.BlockingConnection(parameters)
    ch = connection.channel()
    ch.queue_declare(queue="my_q", durable=False)
    ch.basic_publish(
        exchange="my_ex",
        routing_key="my_rk",
        body=json.dumps(
            {
                "testid": "id-test",
            }
        ),
        properties=pika.BasicProperties(
            content_type="application/json", content_encoding="utf-8"
        ),
    )

def consume():
    parameters = pika.URLParameters(
        "amqp://guest:guest@127.0.0.1/%2F"
    )
    connection = pika.BlockingConnection(parameters)
    channel = connection.channel()
    result = channel.queue_declare(queue='my_q')
    res, prop, msg = channel.basic_get(queue=self.receiveQueueName)
    if res is None:
        # no message from queue
        return {}
    channel.basic_ack()


See Also

  1. 쿠...sal: [컴] RabbitMQ 자료들

Reference

  1. RabbitMQ tutorial - "Hello World!" — RabbitMQ



[컴] vmbox 에서 host os 와 guest os 사이에 clipboard 공유

virtualbox

vmbox 에서 host os 와 guest os 사이에 clipboard 공유

download.virtualbox.org/virtualbox에서VBoxGuestAdditions_*.iso 을 다운로드 해서 guest os 에서 설치하자. 그래야 공유가 가능하다. 기본적으로 c:\Program Files\Oracle\VirtualBox\VBoxGuestAdditions.iso/ 에 있다.

그래서 그냥 아래처럼 "게스트 확장 CD 이미지 삽입" 을 택하면 자동으로 동작한다.

그렇게 하면 자동으로 설치한다.
그리고 vm 을 reboot 하면 된다.

혹시나 안되면 아래작업을 한 번 하고 reboot 을 해보자.
sudo adduser [username] vboxsf
dd

vmbox 에서 한번만 설치하면 된다.?

확실치는 않지만, 만약 vmbox 로 여러개의 linux distro 를 설치한다고 하면, 한 곳에서  VBoxGuestAdditions 를 설치했다면, 다른 linux distro 에서 설치하지 않아도 붙여넣기등의 공유 동작이 동작을 하는 듯 하다.

kali linux

kali linux 에서 다른 작업이 더 필요하다.아래 link 를 참고하자.
아래는 위 link 내용을 정리했다.

순서

  1. repository 확인 : vi /etc/apt/sources.list
  2. update package manger: apt-get update ...
  3. linux header 를 최신으로: apt-get install linux-headers-$(uname -r) -y
  4. VBoxGuestAdditions.iso 를 mount
  5. Desktop 으로 copy 후 VBoxLinuxAdditions.run 를 실행

작업


vi /etc/apt/sources.list
...
apt-get update
apt-get upgrade -y
apt-get dist-upgrade -y
...
cp /media/cdrom/VBoxLinuxAdditions.run /root/Desktop/
cd /root/Desktop/
...
chmod 755 /root/VBoxLinuxAdditions.run
./VBoxLinuxAdditions.run
...
reboot

참고

개인적으로 "게스트 확장 CD 이미지 삽입" 시에 아래같은 error 가 났다.
이경우 위처럼 그냥 직접 mount 해서 실행하면 될 듯 하다.
Could not mount the media/drive 'C:\Program Files\Oracle\VirtualBox\VBoxGuestAdditions.iso' (VERR_PDM_MEDIA_LOCKED).







[컴][알고리즘] Backtracking

백트래킹 / 조합 / 순열 / combination / 알고리즘 /recursive / python

backtracking

Permutation

순열의 성질중 아래 같은 성질을 이용해서 코딩을 한다.

아래 성질을 말로 풀면, (n-1)개에 대한 조합들이 있고, 그 조합에서 1개를 그 사이에 집어넣을 수 있는데, 그 경우의 수가 n 개이다.


def perms(elements):
    if len(elements) ==1:
        # yield elements
        return [elements]
    else:
        ret = []
        for perm in perms(elements[1:]):
            for i in range(len(elements)):
                # 한개를 정하고, 그 한개 이외의 값들을 permutation 을 하고, 
                # 그 한개의 위치만 바꾼다.

                # nb elements[0:1] works in both string and list contexts
                # yield perm[:i] + elements[0:1] + perm[i:]
                ret.append(perm[:i] + elements[0:1] + perm[i:])
        return perm

perms([1,2,3])

return of perms() perm elements i elements[0:1] perm[:i] + elements[0:1] + perm[i:]
[[3]] [3] [2,3] 0 [2] [2,3]
[[3]] [3] [2,3] 1 [2] [3,2]
[[2, 3], [3, 2]] [2,3] [1,2,3] 0 [1] [1,2,3]
[[2, 3], [3, 2]] [2,3] [1,2,3] 1 [1] [2,1,3]
[[2, 3], [3, 2]] [2,3] [1,2,3] 2 [1] [2,3,1]
[[2, 3], [3, 2]] [3,2] [1,2,3] 0 [1] [1,3,2]
[[2, 3], [3, 2]] [3,2] [1,2,3] 1 [1] [3,1,2]
[[2, 3], [3, 2]] [3,2] [1,2,3] 2 [1] [3,2,1]

Combinations

순착적으로만 선택하면 된다.

먼저 조합(combination)의 성질을 조금 알 필요가 있다. combination은 1,3 / 3,1 을 같은 선택으로 본다. 그렇기 때문에 만약 다음처럼 elements 가 있다고 한다면,
elements = [1,2,3]
우리가 앞에서 부터 순차적으로 선택한다면, 마지막 element 인 3을 선택한 이후에, 그 이전 element 를 선택할 필요가 없다. 즉, 1,3 을 선택했다면, 그 다음 2 를 선택해서, 1,3,2 를 선택할 필요가 없다. 왜냐하면, 이것은 1,2,3 에서 이미 만들어진 조합이기 때문이다.

여기서 명심할 것은 다음에 나오는 코드의 주 내용은 가능한 모든 combination 을 찾아주는 방법이지, combination 이 몇개인지를 나타내는 것이 아니다.

recursive version

nCr
ans = []
def backtracking(path, elements, r):
    if r == 0:
        ans.append(list(path)) # copy is needed
        return

    for index, num in enumerate(elements):
        path.append(num) # choose, 선택
        backtracking(path, elements[index + 1:], r - 1)
        path.pop()       # unchoose, 선택해제


backtracking([], [1,2,3], 2)


combinations_with_replacement

ref. 2에 combination python source 가 있다.

`i` 가 현재보고 있는 '자리'가 된다.
각 '자리'에 index 를 써놓는다.
가장 뒷 '자리' 부터 거꾸로 보는데,
그 '자리' 에 있는 index 가 마지막 index가 될 때까지, 보고있는 '자리'를 옮기지 않는다.
마지막 index 가 되면, 보고있는 '자리'를 한자리 앞으로 옮긴다.


'자리' 변경시
현재 보고 있는 '자리' 부터 뒷자리를, 현재 보고있는 '자리'의 index 값보다 +1 한 index 값으로 채운다.
1,1
1,2
1,3
2,1 ==> 1,2와 같다
2,2
2,3
이렇게 순서대로 가야 하는데, 이것은 조합(combination) 이라서 1,2 == 2,1 이 같다. 그래서 새로운 '자리'에 값을 증가 시킬때는 이미 지나온 '자리'에는 새로운 '자리'의 값보다 작은 값을 넣을 필요가 없다.

그래서 아래같은 code 를 사용한다.
indices[i:] = [indices[i] + 1] * (r - i)

def combinations_with_replacement(iterable, r):
    # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
    pool = tuple(iterable)
    n = len(pool)
    if not n and r:
        return
    ret = []
    indices = [0] * r
    # yield tuple(pool[i] for i in indices)
    ret.append(tuple(pool[i] for i in indices))
    while True:
        for i in reversed(range(r)):
            if indices[i] != n - 1:
                break
        else:
            return
        indices[i:] = [indices[i] + 1] * (r - i)
        # yield tuple(pool[i] for i in indices)
        ret.append(tuple(pool[i] for i in indices))

combinations_with_replacement([4,5,6,7], 3)

indices

indices r i r-i indices[i] n-1 indices[i:] [indices[i] + 1] * (r - i) return
[0, 0, 0] 3 i=2 1 0 3 [0] [1] [(4, 4, 4)]
[0, 0, 1] 3 i=2 1 1 3 [1] [2] [(4, 4, 4), (4, 4, 5)]
[0, 0, 2] 3 i=2 1 2 3 [2] [3] [(4, 4, 4), (4, 4, 5), (4, 4, 6)]
[0, 0, 3] 3 i=1 2 0 3 [0, 3] [1, 1] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7)]
[0, 1, 1] 3 i=2 1 1 3 [1] [2] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5)]
[0, 1, 2] 3 i=2 1 2 3 [2] [3] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6)]
[0, 1, 3] 3 i=1 2 1 3 [1, 3] [2, 2] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7)]
[0, 2, 2] 3 i=2 1 2 3 [2] [3] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6)]
[0, 2, 3] 3 i=1 2 2 3 [2, 3] [3, 3] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7)]
[0, 3, 3] 3 i=0 3 0 3 [0, 3, 3] [1, 1, 1] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7), (4, 7, 7)]
[1, 1, 1] 3 i=2 1 1 3 [1] [2] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7), (4, 7, 7), (5, 5, 5)]
[1, 1, 2] 3 i=2 1 2 3 [2] [3] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7), (4, 7, 7), (5, 5, 5), (5, 5, 6)]
[1, 1, 3] 3 i=1 2 1 3 [1, 3] [2, 2] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7), (4, 7, 7), (5, 5, 5), (5, 5, 6), (5, 5, 7)]
[1, 2, 2] 3 i=2 1 2 3 [2] [3] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7), (4, 7, 7), (5, 5, 5), (5, 5, 6), (5, 5, 7), (5, 6, 6)]
[1, 2, 3] 3 i=1 2 2 3 [2, 3] [3, 3] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7), (4, 7, 7), (5, 5, 5), (5, 5, 6), (5, 5, 7), (5, 6, 6), (5, 6, 7)]
[1, 3, 3] 3 i=0 3 1 3 [1, 3, 3] [2, 2, 2] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7), (4, 7, 7), (5, 5, 5), (5, 5, 6), (5, 5, 7), (5, 6, 6), (5, 6, 7), (5, 7, 7)]
[2, 2, 2] 3 i=2 1 2 3 [2] [3] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7), (4, 7, 7), (5, 5, 5), (5, 5, 6), (5, 5, 7), (5, 6, 6), (5, 6, 7), (5, 7, 7), (6, 6, 6)]
[2, 2, 3] 3 i=1 2 2 3 [2, 3] [3, 3] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7), (4, 7, 7), (5, 5, 5), (5, 5, 6), (5, 5, 7), (5, 6, 6), (5, 6, 7), (5, 7, 7), (6, 6, 6), (6, 6, 7)]
[2, 3, 3] 3 i=0 3 2 3 [2, 3, 3] [3, 3, 3] [(4, 4, 4), (4, 4, 5), (4, 4, 6), (4, 4, 7), (4, 5, 5), (4, 5, 6), (4, 5, 7), (4, 6, 6), (4, 6, 7), (4, 7, 7), (5, 5, 5), (5, 5, 6), (5, 5, 7), (5, 6, 6), (5, 6, 7), (5, 7, 7), (6, 6, 6), (6, 6, 7), (6, 7, 7)]

See Also

Reference

  1. `python - How to generate all permutations of a list? - Stack Overflow
  2. itertools — Functions creating iterators for efficient looping — Python 3.8.3 documentation  
  3. https://makefortune2.tistory.com/227
  4. Combinations and Permutations with an Intro to Backtracking 

[컴][알고리즘] BFS breadth-first search

너비 우선 탐색 / bfs /









BFS breadth-first search

vertex s 에서 출발한다.

s 의 adj 는 A, B 이니,
먼저, A 가 level 에 있는지 본다.
A가 level 에 없으니 A에 대한 level (level['A']) 를 set 한다.
그 다음 B 가 level 에 있는지 본다.
B도 level 에 없으니 B에 대한 level (level['B']) 를 set 한다.
그리고 방문했던 A, B는 next 에 저장해 놓는다.
그래서 그 다음에 loop 을 돌 frontier 를 만들게 된다.

frontier 의 각 adj vertex 들을 접근하면서,
각 vertex 가 방문했는지를 level 이 채워져 있는지로 확인한다.
이미 방문한 애들은 그냥 skip 한다.

prarent 는 각 vertex 가 어디서 부터 왔는지를 저장한다. 이것을 거꾸로 하면, path 가 된다.

level = {}
parent = {}

def bfs(s, adj):
    level = {"s": 0}
    parent = {"s": None}
    i = 1
    frontier = [s] # level i-1
    while frontier:
        next = [] # level i
        for u in frontier:
            for v in adj[u]:
                if v not in level:
                    level[v] = i
                    parent[v] = u
                    next.append(v)
        frontier = next
        i += 1     
이 bfs 를 한번 돌리면, 연결된 "하나의 연결된 그래프"의 vertex 들을 전부 visit 하게 된다. 그리고 현재의 연결된 그래프와 연결되지 않은, 나머지 vertex 의 방문을 위해서는 bfs 를 다시 실행해야 한다.

See Also

  1. [컴][알고리즘] Depth-First Search DFS, 깊이우선 탐색

References

  1. 13. Breadth-First Search (BFS) - YouTube


[컴] Apple T2 보안 칩 - Mac 보안

애플 보안 /맥프로 보안 /맥 보안 /

Apple T2 보안 칩

  • Mac computer 에 들어가 있다.
  • 암호화된 저장장치 기능을 제공
  • 맥에 장착된 SSD 에 있는 내용을 암호화 해준다.
  • T2 chip 에 하드웨어로 만들어진 AES 엔진이 있는데, 이것을 이용한다.
  • 이 암호화 작업은 256-bit 키를 사용하고, T2 칩안에 있는 unique id와 묶여서 암호화 한다.
  • T2 chip 에 들어가 있는 향상된 암호화 기술은 line-speed 암호화를 제공한다.
  • 만약 암호화 키를 가지고 있는 T2 Chip 의 일부가 손상되면, 복구할 수 없다. backup 에서 복구해야만 한다.
    • system files, apps, 계정, preferences, 음악, 사진, 영화, 문서
일반 SSD 가 아닌 "T2 보안칩" 이 같이 있는 SSD 를 사용해야 암호화된 저장공간을 이용할 수 있다. 애플은 T2 chip 이 포함된 SSD 를 판매하기 시작했다.

See Also

  1. 쿠...sal: [컴] iOS 보안-시스템 보안

References

  1. 새 Mac의 암호화된 저장 장치에 관하여 - Apple 지원(한글)
  2. About encrypted storage on your new Mac - Apple Support(영문)

[컴][안드로이드] adb 동작

안드로이드 / android / adb how to work /

adb 동작


from : https://www.slideshare.net/tetsu.koba/adbandroid-debug-bridge-how-it-works

  1. adb client 를 실행하면,
  2. client 는 먼저 실행되고 있는 adb server process가 있는지 확인한다.
  3. 없으면 server process 를 시작한다.
  4. server가 시작되면, server 는 local TCP port 5037 에 bind 해서, adb client 에서 보내는 명령을 받을 준비를 한다.
  5. 모든 adb client 는 adb server 와의 통신을 위해 5037 port 를 사용한다.
  6. 서버는 그러고 난후에, 모든 실행되고 있는 기기(devices) 과 connection 들을 설정한다.(set up)
  7. 서버는 "5555~5585 사이의 홀수로 된 port 들"을 scanning 해서, emulator 가 어디있는지를 찾는다.
    • "5555~5585 사이의 홀수로 된 port 들" 은 첫 16개의 emulator 들이 사용하게 된다.
  8. 서버가 scanning 한 port 중에서 adbd(adb 데몬, target phone 에 있다.)을 찾으면, 그 port 와 connection 을 set up한다.
  9. 각 emulator 는 한쌍의 port 를 사용한다.
    • console connection 을 위해 짝수번 port
    • adb connection 을 위해 홀수번 port
Emulator 1, console: 5554
Emulator 1, adb: 5555
Emulator 2, console: 5556
Emulator 2, adb: 5557
and so on...
  1. emulator 가 port 5555 를 통해 adb 에 연결됐으면, emulator 의 console 은 5554 port 에서 listen (수신대기)하고 있는 것이다.
  2. 서버가 모든 기기들과 connection 을 맺으면,
  3. 그 기기들에 대해서 adb command 를 사용할 수 있다.
  • 서버는 device 에 대한 연결을 관리하고, 여러 adb client 로 부터 오는 command 들을 handle 한다. 그래서 특정 device 를 control 하기 위해 특정 client 를 사용할 필요는 없다.

from : https://www.slideshare.net/tetsu.koba/adbandroid-debug-bridge-how-it-works

Reference

  1. Android Debug Bridge (adb) | Android Developers
  2. ADB(Android Debug Bridge): How it works?

[컴][안드로이드] 안드로이드폰을 pc에서 control 하는 방법 - scrcpy

get your phone alternative/ 폰을 windows 에서 control 통제 / 맥에서 통제 / 안드로이드폰 / 안드로이드 pc 에서 조정 / mac에서 조정 / 맥에서 조정

scrcpy

adb 를 통해서 android 를 pc 에서 제어할 수 있게 해주는 tool 이다.

설치

아래 경로에서 download 해서 설치하면 된다.

chocolatey 로 설치

chcolatey 로도 설치가 가능하다.
choco install scrcpy
choco install adb    # if you don't have it yet

over TCP/IP

기본적으로 adb 는 usb 를 연결해서 사용하는 것이었다. 그런데 이제, 무선으로도 사용할 수 있게 됐다. 그래서 자연스럽게 adb 를 이용하는 scrcpy 도 무선으로 사용가능하다.

하지만 초기설정은 usb 로 해줘야 한다. 이것도 rooting 이 되어 있다면, ADBWireless 같은 app 을 이용해서 phone 에서 할 수 있다.
  1. 폰은 당연히 '개발자 옵션' 에서 'usb 디버깅' 옵션을 켜 놔야 한다.
  2. usb를 꽂고,
  3. adb tcpip 5555, (다른 port 도 가능하다 adb tcpip 5557)
  4. usb 를 뺀다.
  5. adb connect 192.168.0.20 (다른 port 인 경우 adb connect 192.168.0.20:5557)
  6. 핸드폰에 usb 디버깅을 허용하겠냐는 화면이 뜬다. 수락한다.
  7. scrcpy 를 실행
  8. 혹시나 다시 usb mode 로 가고 싶다면, adb usb 를 하면 된다.
  9. 기본 bit-rate 가 8Mbps 라고 한다. 이것을 좀 낮추고 싶다면, scrcpy --bit-rate 2M --max-size 800 (5555 port 가 아니라면,scrcpy --bit-rate 2M --max-size 800 -s 192.168.0.20:5557)로 하면 된다.(참고)
C:\scrcpy>adb kill-server
C:\scrcpy>adb tcpip 5555
restarting in TCP mode port: 5555

C:\scrcpy>adb connect 192.168.0.20
* daemon not running; starting now at tcp:5037
* daemon started successfully
failed to authenticate to 192.168.0.20:5555

C:\scrcpy>adb connect 192.168.0.20
already connected to 192.168.0.20:5555

C:\scrcpy>adb devices
List of devices attached
192.168.0.20:5555       device

C:\scrcpy>scrcpy --bit-rate 2M --max-size 800

back, home 버튼

Add On Screen buttons · Issue #7 · Genymobile/scrcpy · GitHub 에서 대략적으로 필요한 버튼의 정보를 얻을 수 있다.
  • home 버튼 : 마우스 가운데 버튼(또는 ctrl+h)
  • back : 마우스 오른쪽 버튼(또는 ctrl+b)
  • app : ctrl + s
  • ?? : ctrl+m
기타 다른 shortcut 은 아래 link 에서 확인할 수 있다.

options

그밖의 좋은 option 들이 있다. 자세한 사항은 README.md 를 확인하자.
scrcpy --always-on-top
scrcpy --fullscreen
scrcpy --turn-screen-off --stay-awake
scrcpy --render-expired-frames
scrcpy --show-touches 
scrcpy --push-target /sdcard/foo/bar/

한글 붙여넣기

Gcopy and paste 부분에서 설명하는 것처럼, 일반적인 붙여넣기(ctrl+v) 는ascii 만 제대로 붙여넣기가 된다.

제대로 붙여넣기를 하려면, android clipboard 에 옮기고 붙여넣는 방식(ctrl+shift+v) 를 사용해야 한다.

scrcpy-noconsole.exe

다른 os 에서도 제공하는 것인지는 모르겠지만, scrcpy-noconsole.exe 이 있다. 이것을 이용해서 '바로가기' 를 생성하면 된다.