티스토리 뷰
ebook
동생이 ebook을 샀는데 자기 계정으로 보라고 하길래 어떻게 그냥 뽑아낼 방법은 없을까 좀 뒤져봤는데,
epub 파일의 확장자를 zip 으로 바꾸면
이런식으로 구성되있는 것을 확인할 수 있는데, OEBPS안에 들어가면
ebook에 필요한 컨텐츠들이 들어 있는거 같고..
대충 살펴보면 TEXT 폴더에 들어가서 파일을 살펴보니 위와 같이 암호화 되어 있었다.
META-INF 폴더에 들어가면 아래와 같이
encryption.xml 파일이 들어 있다. 파일명에서 딱 이 해결하면 ebook에 걸려 있는 DRM을 해제할 수 있을 것 같은. 느낌이 온다.
확인해보면 AES 로 해당 파일이 암호화 되어 있다. ds:KeyInfo 에 들어갈 key만 안다고 끝이 아니고
이게 모드랑 초기화 벡터?였나 그것도 알아야 될텐데 그래도 혹시 모르니까 x64dbg에 플러그인 추가해서 좀 뒤져봤는데 스트레스만 받았다.
그냥 스샷찍어서 그런게 훨씬 효율적으로 작업하는 방향인듯 하다.
아무튼 헛짓거리하다가 그냥 캡쳐-리사이즈-PDF병합 이런식으로 하기로 했다.
일단
ebook viewer 띄운 다음에 content의 사이즈를 확인했다.
import mouseEvents from "global-mouse-events";
mouseEvents.on("mousedown", (event) => {
console.log(event); // { x: 2962, y: 483, button: 1 }
});
이렇게 ebook viewer에서 컨텐츠 포함된 부분의 좌표를 확인했다.
const topLeft = { x: 1165, y: 107, };
const bottomRight = { x: 1914, y: 977 };
bottomRight 좌표를 클릭하면 다음페이지로 넘어가는 거를 확인했고,
다음 버튼을 누르면 viewer의 왼쪽에 > 이런 아이콘이 등장해서 마우스를 잠깐 아래로 내려줘야했다.
const hideIconPos = { x: 1914, y: 1008 };
robotjs 라이브러리 활용하여 마우스 이동이랑 클릭을 자동화하고,
screenshot-desktop 라이브러리 활용하여 스크린샷을 찍었다.
import robot from "robotjs";
import screenshot from "screenshot-desktop";
const topLeft = { x: 1165, y: 107 };
const bottomRight = { x: 1914, y: 977 };
const TOTAL_PAGE = 293;
// 다음으로 넘기기 위치
const nextPos = bottomRight;
// > 아이콘 숨기기 위해 마우스가 이동해야할 위치
const hideIconPos = { x: 1905, y: 1008 };
(async () => {
//
robot.moveMouse(hideIconPos.x, hideIconPos.y);
let cnt = 0;
while (cnt < TOTAL_PAGE) {
const filename = cnt + ".png";
// 사진찍고
await screenshot({ filename: filename });
// 다음 페이지로 넘기고
robot.moveMouse(nextPos.x, nextPos.y);
robot.mouseClick();
// 로딩 기다렸다가
await sleep(500);
// 마우스 위치 아래로 내리기
robot.moveMouse(hideIconPos.x, hideIconPos.y);
cnt++;
}
})();
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
}
이렇게 스크린샷 다 찍은 다음
이미지 자르고 여백 좀 추가해서 pdf로 만들어줬다.
import fs from "node:fs";
import path from "node:path";
import { PDFDocument } from "pdf-lib";
import sharp from "sharp";
const MARGIN = 40;
const TOP_MARGIN = 20;
const CROP = 20;
const pdfDoc = await PDFDocument.create();
const pngFiles = fs
.readdirSync("./412")
.filter((file) => file.endsWith(".png"));
pngFiles.sort((a, b) => +a.split(".")[0] - +b.split(".")[0]);
for (const filename of pngFiles) {
const filePath = path.join("./412", filename);
const { width, height } = await sharp(filePath).metadata();
const image = await sharp(filePath)
.extract({
left: 1165,
top: 107,
width: 1914 - 1165,
height: 977 - 107,
})
.toBuffer();
const imageData = await pdfDoc.embedPng(image);
const page = pdfDoc.addPage([
imageData.width + 2 * MARGIN,
imageData.height + 2 * MARGIN + TOP_MARGIN,
]);
page.drawImage(imageData, {
x: MARGIN,
y: MARGIN + TOP_MARGIN,
width: imageData.width,
height: imageData.height,
});
console.log(filename);
}
const pdfData = await pdfDoc.save();
fs.writeFileSync("result.pdf", pdfData);
암튼 이렇게 ebook 불법 복제를 해봤다.
볼만한데 화질이 뛰어나지 않아서 불법 복제한 느낌이 너무 난다.
나중에 OCR 활용해서 텍스트 뽑아낸 다음, pdf에서 텍스트로 인식할 수 있게 만들어봐야겠다.
'history | grep' 카테고리의 다른 글
240617/잠수 (0) | 2024.06.19 |
---|---|
240616/키위 (0) | 2024.06.17 |
240612/cascadia (0) | 2024.06.13 |
240610/잡념 (0) | 2024.06.11 |
240606/생신 (0) | 2024.06.07 |
- Total
- Today
- Yesterday
- node.js
- DB 생성
- 개발자면접
- 투포인터 연습
- 최소공통조상
- 롱베케이션
- 투포인터
- create db
- 서버점검
- create databases;
- MOD
- MySQL
- 다이나밍프로그래밍
- 은둔청년체험
- 동적프로그래밍
- 로드나인
- 서버개발
- 그래프
- 면접비
- BFS
- 다이나믹프로그래밍
- 면접질문
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |