BLACK CAT PROGRAMMER

pdf tools

有時如果要將幾份pdf 合成一份,或者刪除某幾頁,要俾錢的 acrobat 先做到,但明明很簡單,所以不如自己寫一段仔python,用上免費的library…

有三個功能,
第一個是合併幾份pdf
第二個是拆散pdf
第三個是抽取其中某幾頁

from PyPDF2 import PdfFileWriter, PdfFileReader, PdfFileMerger
import sys
import os
           
def merge(pdf_list):
    input_pdf = pdf_list[:-1]
    output_pdf = pdf_list[-1]
    # check file exists
    for pdf in input_pdf:
        if not os.path.exists(pdf):
            print("error: {} not exists".format(pdf))
            return False
    if os.path.exists(output_pdf):
        print("error output file {} already exists".format(output_pdf))

    merger = PdfFileMerger()
    for pdf in input_pdf:
        merger.append(open(pdf, 'rb'))

    with open(output_pdf, 'wb') as fout:
        merger.write(fout)

def split(input_pdf):
    if not os.path.exists(input_pdf):
        print("error. file {} not exists".format(input_pdf))
        return False

    inputpdf = PdfFileReader(open(input_pdf, "rb"))

    for i in range(inputpdf.numPages):
        output = PdfFileWriter()
        output.addPage(inputpdf.getPage(i))
        with open("{}-page{}.pdf".format(input_pdf, i), "wb") as outputStream:
            output.write(outputStream)

def extract(input_pdf, start, end):
    inputpdf = PdfFileReader(open(input_pdf, "rb"))
    input_name = os.path.splitext(input_pdf)[0]
    output = PdfFileWriter()
    output_name = "{}_{}-{}.pdf".format(input_name, start, end)
    outputStream = open(output_name, "wb")

    end = min(inputpdf.numPages+1,end+1)

    print("extract {} from page {} to page {} to file {}".format(input_pdf, start, end, output_name))
    for i in range(start, end):
        output.addPage(inputpdf.getPage(i-1))
    output.write(outputStream)

def help():
    print("{} ACTION <ip or subnet of the target> [range of the port]".format(sys.argv[0]))
    print("ACTION")
    print("  merge <pdf separated by space}")
    print("  split input.pdf")
    print("  extract input.pdf <start page>[:end page]")
    
    
if __name__ == "__main__":
    if len(sys.argv) < 2:
        help()
        exit()
    if sys.argv[1] == "merge":
        if len(sys.argv) < 4:
            print("at least two pdf files to be merged")
            help()
            exit()
        else:
            merge(sys.argv[2:])

    elif sys.argv[1] == "split":
        if len(sys.argv) < 3:
            print("at least two pdf files to be merged")
            help()
            exit()
        else:
            split(sys.argv[2])

    elif sys.argv[1] == "extract":
        if len(sys.argv) < 4:
            help()
            exit()
        else:
            input_pdf  = sys.argv[2]
            page_range = sys.argv[3].split(":")
            start = int(page_range[0]) 
            end = int(page_range[1]) if len(page_range) > 1 else start

            extract(input_pdf, start, end)
Posted in notesTagged ,

Setting up ssh with private and public key pair

Setting up ssh with private and public key pair

Steps:

  1. Create the key pair on the source server without passphase protection by below command

    # ssh-keygen -t rsa -b 4096

    Then the private key: id_rsa and the public key: id_rsa.pub should be created. The default key file path should be ~/.ssh/id_rsa and without passphase

  2. Change the private key permission to 600
    ** Please keep this private key safely. It is just like your account password **

    # chmod 600 ~/.ssh/id_rsa

  3. Copy the public key file to destination server

    # scp id_rsa.pub [user]@[destination_server]:~/.ssh/ id_rsa.pub

  4. Append the public key to the authorized_keys under the home/.ssh directory. If the host does not have authorized_keys, create an empty file and set the file permission to 600. Then remove the public key file.

    # cat id_rsa.pub >> ~/.ssh/authorized_keys
    # rm id_rsa.pub

  5. Try to ssh from the source server to destination server with the private key

    # ssh [user]@[destination_server] –i ~/.ssh/id_rsa

Fixing Key Permissions And Ownership

Both the host and the client should have the following permissions and owners:

  • ~/.ssh permissions should be 700
  • ~/.ssh should be owned by your account
  • ~/.ssh/authorized_keys permissions should be 600
  • ~/.ssh/authorized_keys should be owned by your account

Client environments should additionally have the following permissions and owners:

  • ~/.ssh/config permissions should be 600
  • ~/.ssh/id_* permissions should be 600

Posted in notesTagged , ,

The C Programming language

平時看了很多書,很想把它們整理,有時可以和朋友分享一下,
所以開始了 BOOK 這個系列的post。
第一本當然由我一生受用的學c神書講起吧。

不用多說吧,作為學 c 的神書,
與其浪費時間在不斷 try and error 和 google ,不如一開始用一點時間,好好看看由 C 的作者所寫的書吧。

認真看過後,發現其實坊間好多作法都是錯的…
還有,書中其實有好多實作的例子。

Posted in bookTagged , ,

python threading

經常忘記 python threading 的用做法,今次寫一個簡單的起手式,方便日後ref

import os
import threading
import time
import queue
import random


class Consumer(threading.Thread):
  def __init__(self, queue, name="consumer"):
    threading.Thread.__init__(self);
    self.name = name
    self.running = True
    self.queue = queue
    self.doneTaskCount = 0
    self.hp = 10

  def run(self):
    while self.running:
      task = self.queue.get();
      time.sleep(2)
      self.doneTaskCount += 1
      print("{} done task (#{}): {}".format(self.name, self.doneTaskCount, task))
      self.hp -= 1
      if self.hp <= 0:
        self.running = False

class Producer(threading.Thread):
  def __init__(self, queue, name="producer"):
    threading.Thread.__init__(self);
    self.name = name
    self.running = True
    self.queue = queue
    self.hp = 10
    self.doneTaskCount = 0

  def run(self):
    while self.running:
      time.sleep(1)
      task = random.random() * 100
      self.queue.put(task)
      self.doneTaskCount += 1
      print("{} created task (#{}): {}".format(self.name, self.doneTaskCount, task))
      
      self.hp -= 1
      if self.hp <= 0:
        self.running = False
          
# main
def main():
  print("start main")
  Q = queue.Queue()
  producer = Producer(Q, "Producer 1")
  consumer = Consumer(Q, "Consumer 1")
  
  producer.start()
  consumer.start()
  
  print(threading.current_thread())
  
  producer.join()
  consumer.join()
  print("performing cleaning, supposed after all thread finished")
  

if __name__ == "__main__":
  main()
Posted in notesTagged , ,

Port scanning

雖然坊間有很多port scanning 的software 可以用,但基於課習,自己寫了段 script 去查看自己部機有咩port 係開左,
為了可以快一點,我把 timeout set 了一秒,連不到就試下一個port,
但結都是很慢,如果想再快一點,可能要加thread 之類,下次有空再加

import socket

host = "192.168.1.1"

def pscan(ip, port):
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(1) # to fasten the scanning speed
        s.connect((ip, port))
        s.close()
        return True
    except:
        return False
    

for i in range(1, 65535, 1):
    if pscan(host, i):
        print("{}:{} is opened".format(host, i))
    if i%100 == 0:
        print("scanned {} ports".format(i)) # print the progress

第二版本,一個用了 thread 去 scan 開了的port ,感覺良好。

import os
import sys
import threading
import time
import queue
import random
import socket
import ipaddress

DEBUG=False

class Task:
    def __init__(self, ip, port, sock_type=socket.SOCK_STREAM):
        self.ip = ip
        self.port = port
        self.sock_type = sock_type

class Consumer(threading.Thread):
    def __init__(self, queue, name="consumer"):
        threading.Thread.__init__(self)
        self.name = name
        self.running = True
        self.queue = queue
        self.doneTaskCount = 0
    

    def run(self):
        while self.queue.empty() == False:
            task = self.queue.get();
            try:
                s = socket.socket(socket.AF_INET, task.sock_type)
                s.settimeout(1)
                s.connect((task.ip, task.port))
                print("{}:{} is opened".format(task.ip, task.port))
                s.close()
            except:
                pass
        #print("{} done".format(self.name))

class Monitor(threading.Thread):
    def __init__(self, queue, report_int=5, name="monitor"):
        threading.Thread.__init__(self)
        self.queue = queue
        self.report_int = report_int

    def run(self):
        while self.queue.empty() == False:
            print("remaining port: {}".format(self.queue.qsize()))
            time.sleep(self.report_int)
        # print("{} done".format(self.name))
      
          
# main
def main(ip_list, start_port=1, end_port=65535, thread_count=1000):
    print("starting main")
    consumer_count = thread_count
    
    Q = queue.Queue()
    
    # queue all target ip and port
    for ip in ip_list:
        if DEBUG:
            print("putting {} {} {}".format(ip, start_port, end_port))
        for i in range(start_port, end_port+1):
            task = Task(str(ip), i)
            Q.put(task)


    print("starting Monitor")
    monitor = Monitor(Q)
    monitor.start()

    print("start scanning with {} threads".format(consumer_count))

    consumer_arr = []
    for i in range(consumer_count):
        consumer_arr.append(Consumer(Q, "Consumer {}".format(i)))
        consumer_arr[i].start()
    
    
    # wait for finish
    for i in range(consumer_count):
        consumer_arr[i].join()
    monitor.join()    
    print("done. cleaning up.")
  
def help():
    print("{} <ip or subnet of the target> [range of the port]".format(sys.argv[0]))
    print("eg:")
    print("scan all of the opened port of the subnet 192.168.1.1 - 192.168.1.254")
    print("  {} 192.168.1.0/24".format(sys.argv[0]))
    print("")
    print("scan the opened port from 1 to 1024 of 192.168.1.1")
    print("  {} 192.168.1.1 1:1024".format(sys.argv[0]))

if __name__ == "__main__":
    ip_list = None
    start_port = 1
    end_port = 65535
    
    if len(sys.argv) < 2:
        help()
        exit()
    
    # parse ip
    try:
        net4 = ipaddress.ip_network(sys.argv[1])
        ips = list(net4.hosts())
        if len(ips) > 0 :
            ip_list = ips
        else:
            ip = ipaddress.ip_address(sys.argv[1])
            ip_list = [str(ip)]
    except Exception as e:
        print("invalid ip format")
        help()
        exit()

    # parse port
    if len(sys.argv) == 3:
        input_ip = sys.argv[1]
        port = sys.argv[2].split(":")
        if len(port) == 1:
            start_port = int(port[0])
            end_port = int(port[0])
        else:
            start_port = int(port[0])
            end_port = int(port[1])

    

    main(ip_list, start_port, end_port)

Posted in notesTagged ,

BASH – Calculating average

原來之前都幾無聊下,寫左咁多「小方遊戲」

#!/bin/bash

# cal_avg.sh
# Calculate the average of a series of numbers.

SCORE="0"
AVERAGE="0"
SUM="0"
NUM="0"

while true; do

  echo -n "Enter your score [0-100%] ('q' for quit): "; read SCORE;

  if (("$SCORE" < "0"))  || (("$SCORE" > "100")); then
    echo "Be serious.  Common, try again: "
  elif [ "$SCORE" == "q" ]; then
    echo "Average rating: $AVERAGE%."
    break
  else
    SUM=$[$SUM + $SCORE]
    NUM=$[$NUM + 1]
    AVERAGE=$[$SUM / $NUM]
  fi

done

echo "Exiting."
Posted in notesTagged

BASH – Guess number

Bash small game

#!/bin/bash

ANSWER=$[$RANDOM%100+1]
GUESS="-1"
FROM="1"
TO="100"

echo "The ANSWER is $ANSWER"

while true; do

	echo -n "Please guess a number [$FROM-$TO]: "; read GUESS;
	if (("$GUESS" < "$TO")) && (("$GUESS" > "$FROM")); then
		if (("$ANSWER" < "$GUESS")); then
			TO=$GUESS;
		elif (("$ANSWER" > "$GUESS")); then
			FROM=$GUESS;	
		elif (("$ANSWER" == "$GUESS")); then
			break
		fi
	else
		echo "Please enter again";
	fi
done

echo "Bingo. The answer is $ANSWER";
Posted in notesTagged