Xiaohongshu User Post
Try for free
No credit card required
Go to Store
Xiaohongshu User Post
share_service/xiaohongshu-user-post
Try for free
No credit card required
获取小红书用户最近发布的帖子
.dockerignore
1# configurations
2.idea
3
4# crawlee and apify storage folders
5apify_storage
6crawlee_storage
7storage
8
9# installed files
10node_modules
11
12# git folder
13.git
14
15# dist folder
16dist
.gitignore
1storage
2apify_storage
3crawlee_storage
4node_modules
5dist
6tsconfig.tsbuildinfo
7storage/*
8!storage/key_value_stores
9storage/key_value_stores/*
10!storage/key_value_stores/default
11storage/key_value_stores/default/*
12!storage/key_value_stores/default/INPUT.json
13
14# Added by Apify CLI
15.venv
bun.lockb
Downloadpackage.json
1{
2 "name": "xiaohongshu-user-post",
3 "version": "0.0.1",
4 "type": "module",
5 "description": "This is an example of an Apify actor.",
6 "engines": {
7 "node": ">=18.0.0"
8 },
9 "dependencies": {
10 "apify": "^3.1.10",
11 "axios": "^1.7.7",
12 "cheerio": "^1.0.0-rc.12",
13 "crypto": "^1.0.1"
14 },
15 "devDependencies": {
16 "@apify/tsconfig": "^0.1.0",
17 "tsx": "^4.6.2",
18 "typescript": "^5.3.3"
19 },
20 "scripts": {
21 "start": "npm run start:dev",
22 "start:prod": "node dist/main.js",
23 "start:dev": "tsx src/main.ts",
24 "build": "tsc",
25 "test": "echo \"Error: oops, the actor has no tests yet, sad!\" && exit 1"
26 },
27 "author": "It's not you it's me",
28 "license": "ISC"
29}
tsconfig.json
1{
2 "extends": "@apify/tsconfig",
3 "compilerOptions": {
4 "module": "NodeNext",
5 "moduleResolution": "NodeNext",
6 "target": "ES2022",
7 "outDir": "dist",
8 "noUnusedLocals": false,
9 "skipLibCheck": true,
10 "lib": ["DOM"]
11 },
12 "include": [
13 "./src/**/*"
14 ]
15}
.actor/Dockerfile
1# Specify the base Docker image. You can read more about
2# the available images at https://docs.apify.com/sdk/js/docs/guides/docker-images
3# You can also use any other image from Docker Hub.
4FROM apify/actor-node:20 AS builder
5
6# Check preinstalled packages
7RUN npm ls crawlee apify puppeteer playwright
8
9# Copy just package.json and package-lock.json
10# to speed up the build using Docker layer cache.
11COPY package*.json ./
12
13# Install all dependencies. Don't audit to speed up the installation.
14RUN npm install --include=dev --audit=false
15
16# Next, copy the source files using the user set
17# in the base image.
18COPY . ./
19
20# Install all dependencies and build the project.
21# Don't audit to speed up the installation.
22RUN npm run build
23
24# Create final image
25FROM apify/actor-node:20
26
27# Check preinstalled packages
28RUN npm ls crawlee apify puppeteer playwright
29
30# Copy just package.json and package-lock.json
31# to speed up the build using Docker layer cache.
32COPY package*.json ./
33
34# Install NPM packages, skip optional and development dependencies to
35# keep the image small. Avoid logging too much and print the dependency
36# tree for debugging
37RUN npm --quiet set progress=false \
38 && npm install --omit=dev --omit=optional \
39 && echo "Installed NPM packages:" \
40 && (npm list --omit=dev --all || true) \
41 && echo "Node.js version:" \
42 && node --version \
43 && echo "NPM version:" \
44 && npm --version \
45 && rm -r ~/.npm
46
47# Copy built JS files from builder image
48COPY /usr/src/app/dist ./dist
49
50# Next, copy the remaining files and directories with the source code.
51# Since we do this after NPM install, quick build will be really fast
52# for most source file changes.
53COPY . ./
54
55
56# Run the image.
57CMD npm run start:prod --silent
.actor/actor.json
1{
2 "actorSpecification": 1,
3 "name": "xiaohongshu-user-post",
4 "title": "Scrape single page in TypeScript",
5 "description": "Scrape data from single page with provided URL.",
6 "version": "0.0",
7 "meta": {
8 "templateId": "ts-start"
9 },
10 "input": "./input_schema.json",
11 "dockerfile": "./Dockerfile"
12}
.actor/input_schema.json
1{
2 "title": "Scrape data from a web page",
3 "type": "object",
4 "schemaVersion": 1,
5 "properties": {
6 "url": {
7 "title": "小红书用户的个人主页",
8 "type": "string",
9 "description": "小红书用户的个人主页地址",
10 "editor": "textfield",
11 "prefill": "https://www.xiaohongshu.com/user/profile/669bdb9a000000002401ca91"
12 }
13 },
14 "required": ["url"]
15}
src/frontend.ts
1// @ts-nocheck
2import axios, { type AxiosInstance } from "axios";
3import crypto from "crypto";
4import fs from "fs";
5import { get_search_id, xc_sign } from "./sign";
6
7function md5(str: string) {
8 return crypto.createHash("md5").update(str).digest("hex");
9}
10
11export const AES_KEY = "glt6h61ta7kisow7";
12export const AES_IV = "4hrivgw5s342f9b2";
13function desV2Encrypt(str: string, key = AES_KEY, iv = AES_IV) {
14 const data = Buffer.from(str, "utf8");
15 const keyBuffer = Buffer.from(key, "utf8");
16 const ivBuffer = Buffer.from(iv, "utf8");
17
18 const cipher = crypto.createCipheriv("aes-128-cbc", keyBuffer, ivBuffer);
19 let encrypted = cipher.update(data);
20 encrypted = Buffer.concat([encrypted, cipher.final()]);
21
22 return encrypted.toString("hex");
23}
24
25function cookieMap(cookie: string) {
26 return cookie.split(";").reduce((acc, cur) => {
27 const [key, value] = cur.split("=");
28 return { ...acc, [key.trim()]: value.trim() };
29 }, {});
30}
31
32export default class XHU {
33 #axios: AxiosInstance;
34 private readonly x3: string;
35 private readonly cookie: string;
36
37 constructor(cookie: string, needLogin: boolean = true) {
38 const c = cookieMap(cookie);
39 this.x3 = c["a1"] as string;
40 if (!this.x3) {
41 throw new Error("a1 not found");
42 }
43
44 this.#axios = axios.create({
45 baseURL: "https://edith.xiaohongshu.com",
46 headers: {
47 accept: "application/json, text/plain, */*",
48 "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
49 authorization: "edith.xiaohongshu.com",
50 "cache-control": "no-cache",
51 cookie: cookie,
52 pragma: "no-cache",
53 Origin: "https://www.xiaohongshu.com",
54 Referer: "https://www.xiaohongshu.com",
55 "sec-ch-ua": '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
56 "sec-ch-ua-mobile": "?0",
57 "sec-ch-ua-platform": '"macOS"',
58 "sec-fetch-dest": "empty",
59 "sec-fetch-mode": "cors",
60 "sec-fetch-site": "same-origin",
61 "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
62 },
63 });
64 this.#axios.interceptors.request.use((config) => {
65 const headers = this._preHeaders(config.url!, config.params, config.data);
66 console.log(headers);
67 config.headers = { ...config.headers, ...headers } as any;
68
69 return config;
70 });
71
72 this.#axios.interceptors.response.use((response) => {
73 return response.data;
74 });
75 }
76
77 _preHeaders(url: string, params: any, data: any) {
78 const queryString = new URLSearchParams(params).toString();
79 const fullPath = queryString ? `${url}?${queryString}` : url;
80 let x1 = md5(`url=${fullPath}`);
81 if (data) {
82 x1 = md5(`url=${fullPath}${JSON.stringify(data)}`);
83 }
84 const x2 = "0|0|0|1|0|0|1|0|0|0|1|0|0|0|0|1|0|0|0";
85 const x3 = this.x3;
86 const x4 = Date.now();
87 const mulStr = `x1=${x1};x2=${x2};x3=${x3};x4=${x4};`;
88
89 const xs_hash = desV2Encrypt(Buffer.from(mulStr).toString("base64"));
90 const payload = { signSvn: "55", signType: "x2", appId: "ugc", signVersion: "1", payload: xs_hash };
91 const xs = `XYW_${Buffer.from(JSON.stringify(payload)).toString("base64")}`;
92 const xt = x4;
93
94 const signs = xc_sign(x3, xs, xt + "");
95 const headers = {
96 "X-S": signs["x-s"],
97 "X-T": signs["x-t"],
98 "X-S-Common": signs["x-s-common"],
99 "X-B3-Traceid": signs["x-b3-traceid"],
100 };
101 return headers;
102 }
103
104 async permit({ file_count = 1, scene = "image" }: { file_count: number; scene: string }) {
105 const response = await this.#axios.get("/api/media/v1/upload/creator/permit", {
106 params: {
107 biz_name: "spectrum",
108 scene,
109 file_count,
110 version: "1",
111 source: "web",
112 },
113 });
114
115 console.log(response.data);
116 const tempPermit = response.data.uploadTempPermits[0];
117 const fileId = tempPermit.fileIds[0];
118 const token = tempPermit.token;
119 return [fileId, token];
120 }
121
122 async createNote(
123 title: string,
124 desc: string,
125 noteType: string,
126 ats: any[] = [],
127 topics: any[] = [],
128 imageInfo: object | null = null,
129 videoInfo: object | null = null,
130 postTime: string | null = null,
131 isPrivate: boolean = true
132 ): Promise<any> {
133 if (postTime) {
134 const postDateTime = new Date(postTime);
135 postTime = postDateTime.getTime().toString();
136 }
137 const uri = "/web_api/sns/v2/note";
138 const businessBinds = {
139 version: 1,
140 noteId: 0,
141 noteOrderBind: {},
142 notePostTiming: { postTime: postTime },
143 noteCollectionBind: { id: "" },
144 };
145
146 if (topics.length > 0) {
147 // #理想L[话题]#
148 desc = desc + "\n" + topics.map((topic) => `#${topic.name}[话题]#`).join(" ");
149 }
150
151 const data = {
152 common: {
153 type: noteType,
154 title: title,
155 note_id: "",
156 desc: desc,
157 source: '{"type":"web","ids":"","extraInfo":"{\\"subType\\":\\"official\\"}"}',
158 business_binds: JSON.stringify(businessBinds),
159 ats: ats,
160 hash_tag: topics,
161 post_loc: {},
162 privacy_info: { op_type: 1, type: Number(isPrivate) },
163 },
164 image_info: imageInfo,
165 video_info: videoInfo,
166 };
167 const headers = { Referer: "https://creator.xiaohongshu.com/" };
168 return this.#axios.post(uri, data, { headers, baseURL: "https://edith.xiaohongshu.com" });
169 }
170
171 async getFileStream(filePath: string) {
172 if (filePath.startsWith("http")) {
173 const response = await axios.get(filePath, {
174 responseType: "arraybuffer",
175 });
176 return response.data;
177 } else {
178 return fs.createReadStream(filePath);
179 }
180 }
181
182 public async uploadFile(fileId: string, token: string, filePath: string, contentType: string = "image/jpeg"): Promise<any> {
183 const maxFileSize = 5 * 1024 * 1024;
184 const url = `https://ros-upload.xiaohongshu.com/${fileId}`;
185 if (fs.statSync(filePath).size > maxFileSize && contentType === "video/mp4") {
186 throw new Error("video too large, < 5M");
187 } else {
188 const headers = { "X-Cos-Security-Token": token, "Content-Type": contentType };
189
190 const fileStream = fs.createReadStream(filePath);
191 return axios.put(url, fileStream, { headers });
192 }
193 }
194
195 async createImageNote(title: string, desc: string, files: string[], postTime: string | null = null, ats: any[] = [], topics: any[] = [], isPrivate: boolean = true): Promise<any> {
196 const images = [];
197 for (const file of files) {
198 const [imageId, token] = await this.permit({ file_count: 1, scene: "image" });
199 await this.uploadFile(imageId, token, file);
200 images.push({
201 file_id: imageId,
202 metadata: { source: -1 },
203 stickers: { version: 2, floating: [] },
204 extra_info_json: '{"mimeType":"image/jpeg"}',
205 });
206 }
207 return this.createNote(title, desc, "normal", ats, topics, { images: images }, null, postTime, isPrivate);
208 }
209
210 async myInfo() {
211 return this.#axios.get("/api/galaxy/user/my-info");
212 }
213
214 async posted(page = 1) {
215 return this.#axios.get(`/api/galaxy/creator/note/user/posted?tab=0&page=${page}`);
216 }
217
218 async delete(note_id: string) {
219 return this.#axios.post(
220 "/web_api/sns/capa/postgw/note/delete",
221 {
222 note_id: note_id,
223 },
224 {
225 baseURL: "https://edith.xiaohongshu.com",
226 }
227 );
228 }
229
230 public async getNoteByKeyword(keyword: string, page: number = 1, pageSize: number = 20, sort = "general", noteType = 0) {
231 const uri = "/api/sns/web/v1/search/notes";
232 const data = {
233 keyword,
234 image_formats: ["webp", "jpg", "avif"],
235 page,
236 page_size: pageSize,
237 search_id: get_search_id(),
238 sort: sort,
239 note_type: noteType,
240 };
241 return this.#axios.post(uri, data);
242 }
243
244 async homefeed() {
245 const params = {"cursor_score":"","num":35,"refresh_type":1,"note_index":26,"unread_begin_note_id":"","unread_end_note_id":"","unread_note_count":0,"category":"homefeed.movie_and_tv_v3","search_key":"","need_num":10,"image_formats":["jpg","webp","avif"],"need_filter_image":false};
246 return this.#axios.post("/api/sns/web/v1/homefeed", params);
247 }
248 async feed(source_note_id: string, xsec_token: string) {
249 const params = {
250 source_note_id: source_note_id,
251 image_formats: ["jpg", "webp", "avif"],
252 extra: {
253 need_body_topic: "1",
254 },
255 xsec_source: "pc_feed",
256 xsec_token: xsec_token,
257 };
258 console.log(params);
259
260 return this.#axios.post("/api/sns/web/v1/feed", params);
261 }
262}
263
264const cookie = `abRequestId=19f1d061-93f8-5610-9510-e463f266e2da; webBuild=4.33.2; xsecappid=xhs-pc-web; a1=191c80307b89o84mfkaytvynytnwa47jdgqic27pv30000468253; webId=09913c973e88db4de8b93500c05ba961; acw_tc=67d4dbda18f981864438a09b59df99ffbd781765f73179f2492e8eca5202439d; web_session=030037a1e877ec145768d465a3214a636a4e6f; gid=yjySY8q8iqfWyjySY8q8WkJWDYjlY46iT0v9AUhhvIv9I3q8E04WVS8884KYJ2q8ifKdYYiK`;
265const r = new XHU(cookie, false);
266r.homefeed().then(async (data) => {
267 const item = data.data.items[0]
268
269 await new Promise((resolve) => setTimeout(resolve, 1000));
270 r.feed(item.id, item.xsec_token).then((detail) => {
271 console.log(JSON.stringify(detail.data, null, 2));
272 })
273});
src/main.ts
1// @ts-nocheck
2// Axios - Promise based HTTP client for the browser and node.js (Read more at https://axios-http.com/docs/intro).
3import axios from "axios";
4// Cheerio - The fast, flexible & elegant library for parsing and manipulating HTML and XML (Read more at https://cheerio.js.org/).
5import * as cheerio from "cheerio";
6// Apify SDK - toolkit for building Apify Actors (Read more at https://docs.apify.com/sdk/js/).
7import { Actor } from "apify";
8import XHU from "./frontend.js";
9
10// this is ESM project, and as such, it requires you to specify extensions in your relative imports
11// read more about this here: https://nodejs.org/docs/latest-v18.x/api/esm.html#mandatory-file-extensions
12// note that we need to use `.js` even when inside TS files
13// import { router } from './routes.js';
14
15// The init() call configures the Actor for its environment. It's recommended to start every Actor with an init().
16await Actor.init();
17
18interface Input {
19 url: string;
20}
21// Structure of input is defined in input_schema.json
22const input = await Actor.getInput<Input>();
23if (!input) throw new Error("Input is missing!");
24const { url } = input;
25
26// const cookie = `abRequestId=19f1d061-93f8-5610-9510-e463f266e2da; webBuild=4.33.2; xsecappid=xhs-pc-web; a1=191c80307b89o84mfkaytvynytnwa47jdgqic27pv30000468253; webId=09913c973e88db4de8b93500c05ba961; acw_tc=67d4dbda18f981864438a09b59df99ffbd781765f73179f2492e8eca5202439d; web_session=030037a1e877ec145768d465a3214a636a4e6f; gid=yjySY8q8iqfWyjySY8q8WkJWDYjlY46iT0v9AUhhvIv9I3q8E04WVS8884KYJ2q8ifKdYYiK`;
27// const r = new XHU(cookie, false);
28
29const response = await axios.get(
30url,
31 {
32 headers: {
33 accept: "application/json, text/plain, */*",
34 "accept-language": "en-US,en;q=0.9",
35 "cache-control": "no-cache",
36 "content-type": "application/json;charset=UTF-8",
37 pragma: "no-cache",
38 "sec-ch-ua":
39 '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
40 "sec-ch-ua-mobile": "?0",
41 "sec-ch-ua-platform": '"macOS"',
42 "sec-fetch-dest": "empty",
43 "sec-fetch-mode": "cors",
44 "sec-fetch-site": "same-site",
45 "user-agent":
46 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
47 Cookie:
48 "abRequestId=fb204935-3ff9-5f82-8f18-6fb74c86a42e; acw_tc=594d061c3e470e8551ac518b11738a7b843bcc735d0fdcfc674962de512d65de",
49 },
50 }
51);
52
53console.log(response.data);
54const $ = cheerio.load(response.data);
55const items = $("#userPostedFeeds .note-item").toArray();
56const list = [];
57items.forEach((item) => {
58 const title = $(item).find(".title").text();
59 const image = $(item).find("img").attr("src");
60 const likedCount = $(item).find(".count").text().replace("赞", "0");
61 list.push({ title, image, likedCount });
62});
63
64await Actor.pushData(list);
65
66// Gracefully exit the Actor process. It's recommended to quit all Actors with an exit().
67await Actor.exit();
src/sign.ts
1// @ts-nocheck
2export function xc_sign(a1 = "", x_s = "", x_t = "") {
3 const b1 = "I38rHdgsjopgIvesdVwgIC+oIELmBZ5e3VwXLgFTIxS3bqwErFeexd0ekncAzMFYnqthIhJeSfMDKutRI3KsYorWHPtGrbV0P9WfIi/eWc6eYqtyQApPI37ekmR1QL+5Ii6sdnosjoT5yqtXqqwYrBqoIx++GDi/sVtkIx0sxuwr4qtiIkrwIi/skcc3ICLfI3Oe0utl20DZsL5eDSJejVw0IieexVwL+PtorqthPWKexY8oICR1IErSgVwBGqtRIxE/eDdeVuwjIC0s1qtnIkpKIkRLee3eDoq6cU5sYqtzaDdefzq1zd/eWWF+IxoefutLIEeeDqt7rYrlOoVGIvgeiqtu/YgexjqmIkLwIiDPGamjIvhm+I88IizuBVwlIvGF4eveDS7e1utCIC7sDc==";
4 const common = {
5 s0: 5,
6 s1: "",
7 x0: "1",
8 x1: "3.3.0",
9 x2: "Windows",
10 x3: "xhs-pc-web",
11 x4: "1.4.4",
12 x5: a1,
13 x6: x_t,
14 x7: x_s,
15 x8: b1,
16 x9: mrc(x_t + x_s + b1),
17 x10: 1,
18 };
19 const encodeStr = encodeUtf8(JSON.stringify(common));
20 const x_s_common = b64Encode(encodeStr);
21 const x_b3_traceid = get_b3_trace_id();
22 return {
23 "x-s": x_s,
24 "x-t": x_t,
25 "x-s-common": x_s_common,
26 "x-b3-traceid": x_b3_traceid,
27 };
28}
29
30function get_b3_trace_id() {
31 const chars = "abcdef0123456789";
32 let result = "";
33 for (let i = 0; i < 16; i++) {
34 result += chars.charAt(Math.floor(Math.random() * chars.length));
35 }
36 return result;
37}
38
39function mrc(e) {
40 const ie = [
41 0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685,
42 2657392035, 249268274, 2044508324, 3772115230, 2547177864, 162941995,
43 2125561021, 3887607047, 2428444049, 498536548, 1789927666, 4089016648,
44 2227061214, 450548861, 1843258603, 4107580753, 2211677639, 325883990,
45 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755,
46 2366115317, 997073096, 1281953886, 3579855332, 2724688242, 1006888145,
47 1258607687, 3524101629, 2768942443, 901097722, 1119000684, 3686517206,
48 2898065728, 853044451, 1172266101, 3705015759, 2882616665, 651767980,
49 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705,
50 3099436303, 671266974, 1594198024, 3322730930, 2970347812, 795835527,
51 1483230225, 3244367275, 3060149565, 1994146192, 31158534, 2563907772,
52 4023717930, 1907459465, 112637215, 2680153253, 3904427059, 2013776290,
53 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719,
54 3865271297, 1802195444, 476864866, 2238001368, 4066508878, 1812370925,
55 453092731, 2181625025, 4111451223, 1706088902, 314042704, 2344532202,
56 4240017532, 1658658271, 366619977, 2362670323, 4224994405, 1303535960,
57 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733,
58 3554079995, 1131014506, 879679996, 2909243462, 3663771856, 1141124467,
59 855842277, 2852801631, 3708648649, 1342533948, 654459306, 3188396048,
60 3373015174, 1466479909, 544179635, 3110523913, 3462522015, 1591671054,
61 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443,
62 3233442989, 3988292384, 2596254646, 62317068, 1957810842, 3939845945,
63 2647816111, 81470997, 1943803523, 3814918930, 2489596804, 225274430,
64 2053790376, 3826175755, 2466906013, 167816743, 2097651377, 4027552580,
65 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225,
66 1852507879, 4275313526, 2312317920, 282753626, 1742555852, 4189708143,
67 2394877945, 397917763, 1622183637, 3604390888, 2714866558, 953729732,
68 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, 3624741850,
69 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135,
70 1181335161, 3412177804, 3160834842, 628085408, 1382605366, 3423369109,
71 3138078467, 570562233, 1426400815, 3317316542, 2998733608, 733239954,
72 1555261956, 3268935591, 3050360625, 752459403, 1541320221, 2607071920,
73 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877,
74 83908371, 2512341634, 3803740692, 2075208622, 213261112, 2463272603,
75 3855990285, 2094854071, 198958881, 2262029012, 4057260610, 1759359992,
76 534414190, 2176718541, 4139329115, 1873836001, 414664567, 2282248934,
77 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795,
78 376229701, 2685067896, 3608007406, 1308918612, 956543938, 2808555105,
79 3495958263, 1231636301, 1047427035, 2932959818, 3654703836, 1088359270,
80 936918000, 2847714899, 3736837829, 1202900863, 817233897, 3183342108,
81 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449,
82 601450431, 3009837614, 3294710456, 1567103746, 711928724, 3020668471,
83 3272380065, 1510334235, 755167117,
84 ];
85 let o = -1;
86
87 function rightWithoutSign(num, bit = 0) {
88 return (num >>> bit);
89 }
90
91 for (let n = 0; n < 57; n++) {
92 o = ie[(o & 255) ^ e.charCodeAt(n)] ^ rightWithoutSign(o, 8);
93 }
94 return o ^ -1 ^ 3988292384;
95}
96
97const lookup = [
98 "Z", "m", "s", "e", "r", "b", "B", "o", "H", "Q", "t", "N", "P", "+", "w", "O",
99 "c", "z", "a", "/", "L", "p", "n", "g", "G", "8", "y", "J", "q", "4", "2", "K",
100 "W", "Y", "j", "0", "D", "S", "f", "d", "i", "k", "x", "3", "V", "T", "1", "6",
101 "I", "l", "U", "A", "F", "M", "9", "7", "h", "E", "C", "v", "u", "R", "X", "5"
102];
103
104function tripletToBase64(e) {
105 return lookup[(63 & (e >> 18))] +
106 lookup[(63 & (e >> 12))] +
107 lookup[((e >> 6) & 63)] +
108 lookup[(e & 63)];
109}
110
111function encodeChunk(e, t, r) {
112 let m = [];
113 for (let b = t; b < r; b += 3) {
114 const n = ((16711680 & (e[b] << 16)) +
115 ((e[b + 1] << 8) & 65280) +
116 (e[b + 2] & 255));
117 m.push(tripletToBase64(n));
118 }
119 return m.join('');
120}
121
122function b64Encode(e) {
123 const P = e.length;
124 const W = P % 3;
125 let U = [];
126 const z = 16383;
127 let H = 0;
128 const Z = P - W;
129 while (H < Z) {
130 U.push(encodeChunk(e, H, H + z > Z ? Z : H + z));
131 H += z;
132 }
133 if (W === 1) {
134 const F = e[P - 1];
135 U.push(lookup[F >> 2] + lookup[(F << 4) & 63] + "==");
136 } else if (W === 2) {
137 const F = (e[P - 2] << 8) + e[P - 1];
138 U.push(lookup[F >> 10] + lookup[(F >> 4) & 63] + lookup[(F << 2) & 63] + "=");
139 }
140 return U.join('');
141}
142
143function encodeUtf8(e) {
144 let b = [];
145 const m = encodeURIComponent(e);
146 for (let i = 0; i < m.length; i++) {
147 if (m[i] === "%") {
148 const hex = m.substr(i + 1, 2);
149 b.push(parseInt(hex, 16));
150 i += 2;
151 } else {
152 b.push(m.charCodeAt(i));
153 }
154 }
155 return b;
156}
157
158function base36encode(number, alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ') {
159 if (typeof number !== 'number' || number % 1 !== 0) {
160 throw new TypeError('number must be an integer');
161 }
162
163 let base36 = '';
164 let sign = '';
165
166 if (number < 0) {
167 sign = '-';
168 number = -number;
169 }
170
171 if (0 <= number && number < alphabet.length) {
172 return sign + alphabet[number];
173 }
174
175 while (number !== 0) {
176 const i = number % alphabet.length;
177 number = Math.floor(number / alphabet.length);
178 base36 = alphabet[i] + base36;
179 }
180
181 return sign + base36;
182}
183
184function base36decode(number) {
185 return parseInt(number, 36);
186}
187
188export function get_search_id() {
189 const e = BigInt(Date.now()) << 64n;
190 const t = BigInt(Math.floor(Math.random() * 2147483646));
191 return base36encode(Number(e + t));
192}
Developer
Maintained by Community
Actor Metrics
9 monthly users
-
3 stars
>99% runs succeeded
Created in Sep 2024
Modified 3 months ago
Categories