diff --git a/_config.yml b/_config.yml index caa960f..6510581 100644 --- a/_config.yml +++ b/_config.yml @@ -15,7 +15,7 @@ baidu_push: true # URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' -url: https://www.imqinhao.cn +url: https://imqinhao.cn root: / permalink: :year/:month/:day/:title/ permalink_defaults: @@ -133,12 +133,4 @@ plugin: feed: type: atom path: atom.xml - limit: 20 - -# offline config passed to sw-precache. -service_worker: - maximumFileSizeToCacheInBytes: 5242880 - staticFileGlobs: - - public/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff,woff2} - stripPrefix: public - verbose: true \ No newline at end of file + limit: 20 \ No newline at end of file diff --git a/hexo-offline-popup/.babelrc b/hexo-offline-popup/.babelrc deleted file mode 100644 index 430184f..0000000 --- a/hexo-offline-popup/.babelrc +++ /dev/null @@ -1,33 +0,0 @@ -{ - "env": { - "test": { - "plugins": [ - "istanbul" - ], - "presets": [ - [ - "env", - { - "targets": { - "node": 4 - } - } - ] - ] - } - }, - "ignore": [ - "./src/templates/inject.tpl.js", - "./src/templates/sw-register.tpl.js" - ], - "presets": [ - [ - "env", - { - "targets": { - "node": 4 - } - } - ] - ] -} diff --git a/hexo-offline-popup/.editorconfig b/hexo-offline-popup/.editorconfig deleted file mode 100644 index 5157391..0000000 --- a/hexo-offline-popup/.editorconfig +++ /dev/null @@ -1,17 +0,0 @@ -# This file is for unifying the coding style for different editors and IDEs -# editorconfig.org - -root = true - -[*] -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.{js,styl,html,json}] -indent_size = 4 -indent_style = space - -[*.md] -trim_trailing_whitespace = false diff --git a/hexo-offline-popup/.fecsignore b/hexo-offline-popup/.fecsignore deleted file mode 100644 index 68f0291..0000000 --- a/hexo-offline-popup/.fecsignore +++ /dev/null @@ -1,12 +0,0 @@ -.DS_Store -._.DS_Store -dist -tmp -*.log -*.tmp -node_modules -lib -src/lib/*.tpl.js -coverage -.nyc_output -npm-debug.* diff --git a/hexo-offline-popup/.fecsrc b/hexo-offline-popup/.fecsrc deleted file mode 100644 index d71445a..0000000 --- a/hexo-offline-popup/.fecsrc +++ /dev/null @@ -1,20 +0,0 @@ -{ - "eslint": { - "env": { - "node": true, - "browser": true - }, - - "globals": { - "console": true, - "require": true, - "define": true - }, - - "rules": { - "no-console": 0, - "brace-style": [2, "1tabs"], - "fecs-no-require": "off" - } - } -} diff --git a/hexo-offline-popup/.nycrc b/hexo-offline-popup/.nycrc deleted file mode 100644 index d8d9c14..0000000 --- a/hexo-offline-popup/.nycrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "require": [ - "babel-register" - ], - "sourceMap": false, - "instrument": false -} diff --git a/hexo-offline-popup/.travis.yml b/hexo-offline-popup/.travis.yml deleted file mode 100644 index 71b3da1..0000000 --- a/hexo-offline-popup/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: node_js -node_js: - - "4" - - "6" - - "8" - -cache: yarn -matrix: - fast_finish: true - -after_success: - - yarn add coveralls - - yarn run coverage -- --reporter=text-lcov | ./node_modules/.bin/coveralls - -before_install: yarn global add greenkeeper-lockfile@1 -before_script: greenkeeper-lockfile-update -after_script: greenkeeper-lockfile-upload diff --git a/hexo-offline-popup/CHANGELOG.md b/hexo-offline-popup/CHANGELOG.md deleted file mode 100644 index e69de29..0000000 diff --git a/hexo-offline-popup/LICENSE b/hexo-offline-popup/LICENSE deleted file mode 100644 index e69de29..0000000 diff --git a/hexo-offline-popup/README.md b/hexo-offline-popup/README.md deleted file mode 100644 index 8a5187a..0000000 --- a/hexo-offline-popup/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# hexo-offline-popup - -hexo-offline-popup 是一个 [hexo](https://hexo.io) 插件, 它可加速您的Hexo网站的加载速度,以及网站内容更新弹窗提示。 - -该插件基于停止维护已久的hexo-service-worker插件,并在它的基础上加以改进。 - -## Install - -```bash -npm i hexo-offline-popup --save -``` - -安装后, 运行 `hexo clean && hexo generate` 激活插件. - -## Usage - -如果网站提供的所有内容来自原始服务器,你不需要添加任何配置。只需安装和运行 `hexo clean && hexo generate`。 - -在博客根目录的 `_config.yml` 中添加以下配置. - -```yaml -# offline config passed to sw-precache. -service_worker: - maximumFileSizeToCacheInBytes: 5242880 - staticFileGlobs: - - public/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff,woff2} - stripPrefix: public - verbose: true -``` - -如果你有CDN资源,例: - -```yaml -- https://cdn.some.com/some/path/some-script.js -- http://cdn.some-else.org/some/path/deeply/some-style.css -``` - -将此配置添加到根目录的 `_config.yml` - -```yaml -service_worker: - runtimeCaching: - - urlPattern: /* - handler: cacheFirst - options: - origin: cdn.some.com - - urlPattern: /* - handler: cacheFirst - options: - origin: cdn.some-else.org -``` diff --git a/hexo-offline-popup/appveyor.yml b/hexo-offline-popup/appveyor.yml deleted file mode 100644 index 777a41f..0000000 --- a/hexo-offline-popup/appveyor.yml +++ /dev/null @@ -1,34 +0,0 @@ -# Fix line endings in Windows. (runs before repo cloning) -init: - - git config --global core.autocrlf input - -# Test against these versions of Node.js. -environment: - matrix: - - nodejs_version: "4" - - nodejs_version: "6" - - nodejs_version: "8" - -matrix: - fast_finish: true - -# Install scripts. (runs after repo cloning) -install: - - ps: Install-Product node $env:nodejs_version - - npm install - -cache: - - node_modules - -# Post-install test scripts. -test_script: - - npm test - -# Don't actually build. -build: off - -# Don't actually deploy. -deploy: off - -# Set build version format here instead of in the admin panel. -version: "{build}" diff --git a/hexo-offline-popup/build.sh b/hexo-offline-popup/build.sh deleted file mode 100644 index e69de29..0000000 diff --git a/hexo-offline-popup/lib/config.js b/hexo-offline-popup/lib/config.js deleted file mode 100644 index c58fdab..0000000 --- a/hexo-offline-popup/lib/config.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * @file config for plugin - * @author mj(zoumiaojiang@gmail.com) - */ - -var SW_FILE_NAME = exports.SW_FILE_NAME = 'sw.js'; \ No newline at end of file diff --git a/hexo-offline-popup/lib/index.js b/hexo-offline-popup/lib/index.js deleted file mode 100644 index cf27b89..0000000 --- a/hexo-offline-popup/lib/index.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -var _runSwPrecache = require('./run-sw-precache'); - -var _runSwPrecache2 = _interopRequireDefault(_runSwPrecache); - -var _runSwRegister = require('./run-sw-register'); - -var _runSwRegister2 = _interopRequireDefault(_runSwRegister); - -var _inject = require('./inject'); - -var _inject2 = _interopRequireDefault(_inject); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function serviceWorkerHandler() { - var _this = this; - - return Promise.all([_runSwPrecache2.default.call(this), _runSwRegister2.default.call(this)]).then(function () { - return (0, _inject2.default)(_this.public_dir); - }); -} /** - * @file hexo plugin entry - * @author mj(zoumiaojiang@gmail.com) - */ - -/* global hexo */ - - -hexo.extend.filter.register('before_exit', serviceWorkerHandler); \ No newline at end of file diff --git a/hexo-offline-popup/lib/inject.js b/hexo-offline-popup/lib/inject.js deleted file mode 100644 index f3b2fcb..0000000 --- a/hexo-offline-popup/lib/inject.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = inject; - -var _fs = require('fs'); - -var _fs2 = _interopRequireDefault(_fs); - -var _path = require('path'); - -var _path2 = _interopRequireDefault(_path); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * @file inject service worker to hexo page - * @author mj(zoumiaojiang@gmail.com) - */ - -var injectScriptCon = _fs2.default.readFileSync(_path2.default.join(__dirname, 'templates', 'inject.tpl.js'), 'utf-8'); -var injectScript = ``; - -function inject(publicDir) { - - _fs2.default.readdirSync(publicDir).forEach(function (item) { - var itemPath = _path2.default.resolve(publicDir, item); - - if (_fs2.default.statSync(itemPath).isFile()) { - if (/\.html$/.test(item)) { - var indexHTMLPath = _path2.default.join(publicDir, item); - var fileContent = _fs2.default.readFileSync(indexHTMLPath, 'utf-8').toString(); - - // if it has not been injected before - if (!fileContent.includes(`${injectScript}`)) { - var injectedContent = fileContent.replace(/<\/body>\s*<\/html>\s*$/, `${injectScript}`); - _fs2.default.writeFileSync(indexHTMLPath, injectedContent); - } - } - } else if (_fs2.default.statSync(itemPath).isDirectory()) { - inject(itemPath); - } - }); -} \ No newline at end of file diff --git a/hexo-offline-popup/lib/run-sw-precache.js b/hexo-offline-popup/lib/run-sw-precache.js deleted file mode 100644 index 6c5d893..0000000 --- a/hexo-offline-popup/lib/run-sw-precache.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -exports.default = function () { - var public_dir = this.public_dir, - config = this.config, - log = this.log; - var root = config.root, - service_worker = config.service_worker; - - - var hexoPublicDir = 'public'; - var rootPrefix = root.replace(/\/$/, ''); - var SWPrecacheConfig = Object.assign({ - logger: log.info.bind(log), - replacePrefix: rootPrefix, - staticFileGlobs: [hexoPublicDir + '/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff}'], - stripPrefix: hexoPublicDir, - templateFilePath: _path2.default.resolve(__dirname, 'templates', 'sw-precache.tpl') - }, service_worker); - - return _swPrecache2.default.write(_path2.default.join(public_dir, _config.SW_FILE_NAME), SWPrecacheConfig); -}; - -var _path = require('path'); - -var _path2 = _interopRequireDefault(_path); - -var _swPrecache = require('sw-precache'); - -var _swPrecache2 = _interopRequireDefault(_swPrecache); - -var _config = require('./config'); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } \ No newline at end of file diff --git a/hexo-offline-popup/lib/run-sw-register.js b/hexo-offline-popup/lib/run-sw-register.js deleted file mode 100644 index 6c8df1a..0000000 --- a/hexo-offline-popup/lib/run-sw-register.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -exports.default = function () { - var swRegisterTemplatePath = _path2.default.resolve(__dirname, 'templates', 'sw-register.tpl.js'); - var swRegisterTempleteCon = _fs2.default.readFileSync(swRegisterTemplatePath, 'utf-8'); - var swRegisterCon = swRegisterTempleteCon.replace('__ServiceWorkerName__', _config.SW_FILE_NAME).replace('__BuildVersion__', versionGenerator()); - - var swRegisterDistPath = _path2.default.resolve(this.public_dir, 'sw-register.js'); - - _fs2.default.writeFileSync(swRegisterDistPath, swRegisterCon); - - return Promise.resolve(); -}; - -var _fs = require('fs'); - -var _fs2 = _interopRequireDefault(_fs); - -var _path = require('path'); - -var _path2 = _interopRequireDefault(_path); - -var _config = require('./config'); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * 对于小于 10 的数字向左补全0 - * - * @param {number} value 数字 - * @return {string} 补全后的字符串 - */ -function padding(value) { - return value < 10 ? `0${value}` : value; -} - -/** - * 获取时间戳版本号 - * - * @return {string} 版本号 - */ -/** - * @file run sw-precache - * @author mj(zoumiaojiang@gmail.com) - */ - -/* global public_dir */ -/* eslint-disable fecs-camelcase */ -function versionGenerator() { - var d = new Date(); - - return '' + d.getFullYear() + padding(d.getMonth() + 1) + padding(d.getDate()) + padding(d.getHours()) + padding(d.getMinutes()) + padding(d.getSeconds()); -} \ No newline at end of file diff --git a/hexo-offline-popup/lib/templates/inject.tpl.js b/hexo-offline-popup/lib/templates/inject.tpl.js deleted file mode 100644 index b1b6df0..0000000 --- a/hexo-offline-popup/lib/templates/inject.tpl.js +++ /dev/null @@ -1 +0,0 @@ -window.onload=function(){var a=document.createElement('script'),b=document.getElementsByTagName('script')[0];a.type='text/javascript',a.async=!0,a.src='/sw-register.js?v='+Date.now(),b.parentNode.insertBefore(a,b)}; \ No newline at end of file diff --git a/hexo-offline-popup/lib/templates/sw-precache.tpl b/hexo-offline-popup/lib/templates/sw-precache.tpl deleted file mode 100644 index a9a152f..0000000 --- a/hexo-offline-popup/lib/templates/sw-precache.tpl +++ /dev/null @@ -1,280 +0,0 @@ -/** - * 自动引入模板,在原有 sw-precache 插件默认模板基础上做的二次开发 - * - * 因为是自定导入的模板,项目一旦生成,不支持随 sw-precache 的版本自动升级。 - * 可以到 Lavas 官网下载 basic 模板内获取最新模板进行替换 - * - */ - -/* eslint-disable */ - -'use strict'; - -var precacheConfig = <%= precacheConfig %>; -var cacheName = 'sw-precache-<%= version %>-<%= cacheId %>-' + (self.registration ? self.registration.scope : ''); -var firstRegister = 1; // 默认1是首次安装SW, 0是SW更新 - -<% if (handleFetch) { %> -var ignoreUrlParametersMatching = [<%= ignoreUrlParametersMatching %>]; -<% } %> - -var addDirectoryIndex = function (originalUrl, index) { - var url = new URL(originalUrl); - if (url.pathname.slice(-1) === '/') { - url.pathname += index; - } - return url.toString(); -}; - -var cleanResponse = function (originalResponse) { - // 如果没有重定向响应,不需干啥 - if (!originalResponse.redirected) { - return Promise.resolve(originalResponse); - } - - // Firefox 50 及以下不知处 Response.body 流, 所以我们需要读取整个body以blob形式返回。 - var bodyPromise = 'body' in originalResponse ? - Promise.resolve(originalResponse.body) : - originalResponse.blob(); - - return bodyPromise.then(function (body) { - // new Response() 可同时支持 stream or Blob. - return new Response(body, { - headers: originalResponse.headers, - status: originalResponse.status, - statusText: originalResponse.statusText - }); - }); -}; - -var createCacheKey = function (originalUrl, paramName, paramValue, - dontCacheBustUrlsMatching) { - - // 创建一个新的URL对象,避免影响原始URL - var url = new URL(originalUrl); - - // 如果 dontCacheBustUrlsMatching 值没有设置,或是没有匹配到,将值拼接到url.serach后 - if (!dontCacheBustUrlsMatching || - !(url.pathname.match(dontCacheBustUrlsMatching))) { - url.search += (url.search ? '&' : '') + - encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue); - } - - return url.toString(); -}; - -var isPathWhitelisted = function (whitelist, absoluteUrlString) { - // 如果 whitelist 是空数组,则认为全部都在白名单内 - if (whitelist.length === 0) { - return true; - } - - // 否则逐个匹配正则匹配并返回 - var path = (new URL(absoluteUrlString)).pathname; - return whitelist.some(function (whitelistedPathRegex) { - return path.match(whitelistedPathRegex); - }); -}; - -var stripIgnoredUrlParameters = function (originalUrl, - ignoreUrlParametersMatching) { - var url = new URL(originalUrl); - // 移除 hash; 查看 https://github.com/GoogleChrome/sw-precache/issues/290 - url.hash = ''; - - url.search = url.search.slice(1) // 是否包含 '?' - .split('&') // 分割成数组 'key=value' 的形式 - .map(function (kv) { - return kv.split('='); // 分割每个 'key=value' 字符串成 [key, value] 形式 - }) - .filter(function (kv) { - return ignoreUrlParametersMatching.every(function (ignoredRegex) { - return !ignoredRegex.test(kv[0]); // 如果 key 没有匹配到任何忽略参数正则,就 Return true - }); - }) - .map(function (kv) { - return kv.join('='); // 重新把 [key, value] 格式转换为 'key=value' 字符串 - }) - .join('&'); // 将所有参数 'key=value' 以 '&' 拼接 - - return url.toString(); -}; - - -var addDirectoryIndex = function (originalUrl, index) { - var url = new URL(originalUrl); - if (url.pathname.slice(-1) === '/') { - url.pathname += index; - } - return url.toString(); -}; - -var hashParamName = '_sw-precache'; -var urlsToCacheKeys = new Map( - precacheConfig.map(function (item) { - var relativeUrl = item[0]; - var hash = item[1]; - var absoluteUrl = new URL(relativeUrl, self.location); - var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, <%= dontCacheBustUrlsMatching %>); - return [absoluteUrl.toString(), cacheKey]; - }) -); - -function setOfCachedUrls(cache) { - return cache.keys().then(function (requests) { - // 如果原cacheName中没有缓存任何收,就默认是首次安装,否则认为是SW更新 - if (requests && requests.length > 0) { - firstRegister = 0; // SW更新 - } - return requests.map(function (request) { - return request.url; - }); - }).then(function (urls) { - return new Set(urls); - }); -} - -self.addEventListener('install', function (event) { - event.waitUntil( - caches.open(cacheName).then(function (cache) { - return setOfCachedUrls(cache).then(function (cachedUrls) { - return Promise.all( - Array.from(urlsToCacheKeys.values()).map(function (cacheKey) { - // 如果缓存中没有匹配到cacheKey,添加进去 - if (!cachedUrls.has(cacheKey)) { - var request = new Request(cacheKey, { credentials: 'same-origin' }); - return fetch(request).then(function (response) { - // 只要返回200才能继续,否则直接抛错 - if (!response.ok) { - throw new Error('Request for ' + cacheKey + ' returned a ' + - 'response with status ' + response.status); - } - - return cleanResponse(response).then(function (responseToCache) { - return cache.put(cacheKey, responseToCache); - }); - }); - } - }) - ); - }); - }) - .then(function () { - <% if (skipWaiting) { %> - // 强制 SW 状态 installing -> activate - return self.skipWaiting(); - <% } %> - }) - ); -}); - -self.addEventListener('activate', function (event) { - var setOfExpectedUrls = new Set(urlsToCacheKeys.values()); - - event.waitUntil( - caches.open(cacheName).then(function (cache) { - return cache.keys().then(function (existingRequests) { - return Promise.all( - existingRequests.map(function (existingRequest) { - // 删除原缓存中相同键值内容 - if (!setOfExpectedUrls.has(existingRequest.url)) { - return cache.delete(existingRequest); - } - }) - ); - }); - }).then(function () { - <% if (clientsClaim) { %> - return self.clients.claim(); - <% } %> - }).then(function () { - // 如果是首次安装 SW 时, 不发送更新消息(是否是首次安装,通过指定cacheName 中是否有缓存信息判断) - // 如果不是首次安装,则是内容有更新,需要通知页面重载更新 - if (!firstRegister) { - return self.clients.matchAll() - .then(function (clients) { - if (clients && clients.length) { - clients.forEach(function (client) { - client.postMessage('sw.update'); - }) - } - }) - } - }) - ); -}); - - -<% if (handleFetch) { %> - self.addEventListener('fetch', function (event) { - if (event.request.method === 'GET') { - - // 是否应该 event.respondWith(),需要我们逐步的判断 - // 而且也方便了后期做特殊的特殊 - var shouldRespond; - - - // 首先去除已配置的忽略参数及hash - // 查看缓存简直中是否包含该请求,包含就将shouldRespond 设为true - var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching); - shouldRespond = urlsToCacheKeys.has(url); - - // 如果 shouldRespond 是 false, 我们在url后默认增加 'index.html' - // (或者是你在配置文件中自行配置的 directoryIndex 参数值),继续查找缓存列表 - var directoryIndex = '<%= directoryIndex %>'; - if (!shouldRespond && directoryIndex) { - url = addDirectoryIndex(url, directoryIndex); - shouldRespond = urlsToCacheKeys.has(url); - } - - // 如果 shouldRespond 仍是 false,检查是否是navigation - // request, 如果是的话,判断是否能与 navigateFallbackWhitelist 正则列表匹配 - var navigateFallback = '<%= navigateFallback %>'; - if (!shouldRespond && - navigateFallback && - (event.request.mode === 'navigate') && - isPathWhitelisted(<%= navigateFallbackWhitelist %>, event.request.url) - ) { - url = new URL(navigateFallback, self.location).toString(); - shouldRespond = urlsToCacheKeys.has(url); - } - - // 如果 shouldRespond 被置为 true - // 则 event.respondWith()匹配缓存返回结果,匹配不成就直接请求. - if (shouldRespond) { - event.respondWith( - caches.open(cacheName).then(function (cache) { - return cache.match(urlsToCacheKeys.get(url)).then(function (response) { - if (response) { - return response; - } - throw Error('The cached response that was expected is missing.'); - }); - }).catch(function (e) { - // 如果捕获到异常错误,直接返回 fetch() 请求资源 - console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e); - return fetch(event.request); - }) - ); - } - } - }); - - -<% if (swToolboxCode) { %> -// *** Start of auto-included sw-toolbox code. *** -<%= swToolboxCode %> -// *** End of auto-included sw-toolbox code. *** -<% } %> - -<% if (runtimeCaching) { %> -// Runtime cache 配置转换后的 toolbox 代码. -<%= runtimeCaching %> -<% } %> -<% } %> - -<% if (importScripts) { %> - importScripts(<%= importScripts %>); -<% } %> - -/* eslint-enable */ diff --git a/hexo-offline-popup/lib/templates/sw-register.tpl.js b/hexo-offline-popup/lib/templates/sw-register.tpl.js deleted file mode 100644 index 03802ac..0000000 --- a/hexo-offline-popup/lib/templates/sw-register.tpl.js +++ /dev/null @@ -1 +0,0 @@ -navigator.serviceWorker&&navigator.serviceWorker.register('/__ServiceWorkerName__?v=__BuildVersion__').then(function(){navigator.serviceWorker.addEventListener('message',function(a){if('sw.update'===a.data){let a=document.querySelector('meta[name=theme-color]'),b=document.createElement('div');a&&(a.content='#000'),b.innerHTML='

\u64cd\u4f5c\u901a\u77e5

\u5df2\u66f4\u65b0\u6700\u65b0\u7248\u672c\uff08\u5237\u65b0\u751f\u6548\uff09
×
',document.body.appendChild(b),setTimeout(function(){document.getElementById('app-refresh').className+=' app-refresh-show'},16)}})}); \ No newline at end of file diff --git a/hexo-offline-popup/package.json b/hexo-offline-popup/package.json deleted file mode 100644 index 2919f9e..0000000 --- a/hexo-offline-popup/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "_from": "hexo-offline-popup", - "_id": "hexo-offline-popup@1.0.3", - "_inBundle": false, - "_integrity": "sha512-Lhv0vAXffJVwqMObyK+EjW4lfsjmzj+sVnCJc/pssmj9W+O+Mal57bgLV5dLuAV82u/57TQ4BtvdpLOTtkH99Q==", - "_location": "/hexo-offline-popup", - "_phantomChildren": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.4", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - }, - "_requested": { - "type": "tag", - "registry": true, - "raw": "hexo-offline-popup", - "name": "hexo-offline-popup", - "escapedName": "hexo-offline-popup", - "rawSpec": "", - "saveSpec": null, - "fetchSpec": "latest" - }, - "_requiredBy": [ - "#USER", - "/" - ], - "_resolved": "https://registry.npmjs.org/hexo-offline-popup/-/hexo-offline-popup-1.0.3.tgz", - "_shasum": "4a1d7e3e7280001c710315dcc65db753233ed81f", - "_spec": "hexo-offline-popup", - "_where": "D:\\qinhao\\hexo", - "author": { - "name": "colsrch" - }, - "bugs": { - "url": "https://github.com/Colsrch/hexo-offline-popup/issues" - }, - "bundleDependencies": false, - "dependencies": { - "babel-cli": "^6.26.0", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-babili": "^0.1.4", - "babel-preset-env": "^1.7.0", - "babel-register": "^6.26.0", - "cross-env": "^7.0.2", - "fecs": "^1.6.4", - "fs-extra": "^9.0.1", - "nyc": "^15.1.0", - "pre-commit": "^1.2.2", - "rimraf": "^3.0.2", - "sw-precache": "^5.2.1", - "tap": "^14.10.7" - }, - "deprecated": false, - "description": "实现加速Hexo网站的加载速度、网站内容更新弹窗提示", - "devDependencies": {}, - "directories": { - "lib": "lib", - "test": "test" - }, - "homepage": "https://github.com/Colsrch/hexo-offline-popup#readme", - "keywords": [ - "hexo-offline-popup" - ], - "license": "ISC", - "main": "lib/index.js", - "name": "hexo-offline-popup", - "repository": { - "type": "git", - "url": "git+https://github.com/Colsrch/hexo-offline-popup.git" - }, - "scripts": { - "test": "tap test/*.js" - }, - "version": "1.0.3" -} diff --git a/hexo-offline-popup/test/specs/inject.test.js b/hexo-offline-popup/test/specs/inject.test.js deleted file mode 100644 index 6717199..0000000 --- a/hexo-offline-popup/test/specs/inject.test.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file inject to html file's test - * @author mj(zoumiaoijiang@gmail.com) - */ - -import tap from 'tap'; -import fs from 'fs-extra'; -import path from 'path'; -import injectSWRegisterEntry from '../../src/inject'; - - -let test = tap.test; - -test('inject should inject script when index.html presents', t => { - let publicDir = path.resolve('./inject.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirSync(publicDir); - - let html = [ - '', - '', - ' ', - '' - ].join('\n'); - - let indexHTMLPath = path.join(publicDir, 'index.html'); - fs.writeFileSync(indexHTMLPath, html); - - injectSWRegisterEntry(publicDir); - let content = fs.readFileSync(indexHTMLPath, 'utf-8'); - t.ok(content.includes('')); - t.ok(content.includes('sw-register.js')); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); -}); - -test('inject should success when html file in sub dir', t => { - let publicDir = path.resolve('./inject.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirpSync(path.resolve(publicDir, 'subdir')); - let html = [ - '', - '', - ' ', - '' - ].join('\n'); - - let indexfirstLevelHTMLPath = path.join('./inject.test', 'index.html'); - let index2LevelHTMLPath = path.join('./inject.test/subdir', 'index.html'); - - fs.writeFileSync(indexfirstLevelHTMLPath, html); - fs.writeFileSync(index2LevelHTMLPath, html); - - injectSWRegisterEntry(publicDir); - let content = fs.readFileSync(indexfirstLevelHTMLPath, 'utf-8'); - let content2 = fs.readFileSync(index2LevelHTMLPath, 'utf-8'); - t.ok(content.includes('')); - t.ok(content2.includes('')); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); -}); - -test('inject should not throw when index.html is not found', t => { - let publicDir = path.resolve('./inject.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirSync(publicDir); - - t.doesNotThrow(() => injectSWRegisterEntry(publicDir)); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); -}); - -test('inject-sw-register should not inject script agian once injected', t => { - let publicDir = path.resolve('./inject.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirSync(publicDir); - - let html = [ - '', - '', - ' ', - '' - ].join('\n'); - - let indexHTMLPath = path.join(publicDir, 'index.html'); - fs.writeFileSync(indexHTMLPath, html); - - injectSWRegisterEntry(publicDir); - let content = fs.readFileSync(indexHTMLPath, 'utf-8'); - - injectSWRegisterEntry(publicDir); - let newContent = fs.readFileSync(indexHTMLPath, 'utf-8'); - - t.equal(content, newContent); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); -}); diff --git a/hexo-offline-popup/test/specs/run-sw-precache.test.js b/hexo-offline-popup/test/specs/run-sw-precache.test.js deleted file mode 100644 index dbdd4e3..0000000 --- a/hexo-offline-popup/test/specs/run-sw-precache.test.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file test of sw-precache - * @author mj(zoumiaojiang@gmail.com) - */ - -import {test} from 'tap'; -import fs from 'fs-extra'; -import path from 'path'; -import runSWPrecache from '../../src/run-sw-precache'; -import {SW_FILE_NAME} from '../../src/config'; - -/* eslint-disable fecs-camelcase */ -test('run-sw-precache should generate sw.js when index.html presents', t => { - let publicDir = path.resolve('./run-sw-precache.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirpSync(publicDir); - - let context = { - public_dir: publicDir, - config: { - root: '/', - service_worker: {} - }, - log: console - }; - - let cleanup = () => { - fs.existsSync(publicDir) && fs.removeSync(publicDir); - }; - - return runSWPrecache.call(context).then(() => { - let workerPath = path.join(publicDir, SW_FILE_NAME); - t.ok(fs.existsSync(workerPath)); - cleanup(); - t.end(); - }, error => { - console.error(error); - cleanup(); - t.end(); - }); -}); - -test('run-sw-precache should generate sw.js when use custom sw.tmpl', t => { - let publicDir = path.resolve('./run-sw-precache.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirSync(publicDir); - - let context = { - public_dir: publicDir, - config: { - root: '/', - service_worker: {} - }, - log: console - }; - - let cleanup = () => { - fs.existsSync(publicDir) && fs.removeSync(publicDir); - }; - - return runSWPrecache.call(context).then(() => { - let workerPath = path.join(publicDir, SW_FILE_NAME); - let swCon = fs.readFileSync(workerPath, 'utf-8'); - t.ok(swCon.includes('sw.update')); - cleanup(); - t.end(); - }, error => { - console.error(error); - cleanup(); - t.end(); - }); -}); diff --git a/hexo-offline-popup/test/specs/run-sw-register.test.js b/hexo-offline-popup/test/specs/run-sw-register.test.js deleted file mode 100644 index d960e1a..0000000 --- a/hexo-offline-popup/test/specs/run-sw-register.test.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file inject to html file's test - * @author mj(zoumiaoijiang@gmail.com) - */ - -import tap from 'tap'; -import fs from 'fs-extra'; -import path from 'path'; -import runSWRegister from '../../src/run-sw-register'; - -/* eslint-disable fecs-camelcase */ -let test = tap.test; - -test('sw-regisrer should generate ok', t => { - let publicDir = path.resolve('./sw-register.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirSync(publicDir); - - let context = { - public_dir: publicDir, - config: { - root: '/', - service_worker: {} - }, - log: console - }; - - return runSWRegister.call(context).then(() => { - let workerPath = path.join(publicDir, 'sw-register.js'); - let swRegisterFileCon = fs.readFileSync(workerPath, 'utf-8'); - - t.ok(fs.existsSync(workerPath)); - t.ok(swRegisterFileCon.includes('sw.js')); - t.ok(/sw\.js\?v=\d{14}/.test(swRegisterFileCon)); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); - }, error => { - console.error(error); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); - }); -}); diff --git a/source/CNAME b/source/CNAME index 4b66776..aa5c044 100644 --- a/source/CNAME +++ b/source/CNAME @@ -1 +1 @@ -www.imqinhao.cn \ No newline at end of file +imqinhao.cn \ No newline at end of file diff --git a/source/_posts/3G.md b/source/_posts/3G.md index b80e6c9..73952a6 100644 --- a/source/_posts/3G.md +++ b/source/_posts/3G.md @@ -6,11 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-03-07 11:25:00 -music: - enable: true - server: netease - type: song - id: 1411358329 comments: true tags: - 通信技术 diff --git "a/source/_posts/5G\347\275\221\347\273\234\344\274\230\345\214\226.md" "b/source/_posts/5G\347\275\221\347\273\234\344\274\230\345\214\226.md" new file mode 100644 index 0000000..4094ff1 --- /dev/null +++ "b/source/_posts/5G\347\275\221\347\273\234\344\274\230\345\214\226.md" @@ -0,0 +1,199 @@ +--- +title: 5G网络优化 +author: + name: 覃浩 + avatar: https://cdn.jsdelivr.net/gh/queen999/ImageHosting//imagesavatar.jpg + url: https://www.imqinhao.cn +categories: 通信技术 +date: 2020-10-01 10:00:00 +comments: true +--- + +5G覆盖指标定义 + +覆盖率 + +覆盖优化整体流程 + +NR覆盖类问题及优化方案 + + + +# 5G覆盖指标定义 + +## 广播信道 + +SS参考信号接收功率(SS-RSRP) :测量频段带宽上承载辅同步信号(SS) 的资源单元接收功率贡献的线性平均值; + +SS信噪比和干扰比(SS SINR)定义为”携带辅同步信号的资源单元的功率贡献的线性平均值”除以"在相同频率带宽内承载辅同步信号的资源单元的噪声和干扰功率的线性平均值”; + +## 业务信道 + +CSI参考信号接收功率(CSI-RSRP) 被定义为在所配置的CSI中在所考虑的测量频率带宽内承载用于RSRP测量的CSI参考信号的资源单元的功率贡献上的线性平均值; + +CSI信噪比和干扰比(CSI-SINR) 被定义为”携带CSI参考信号的资源单元的功率贡献的线性平均值”除以”携带CSI参考信号的资源单元在相同频率带宽内的参考信号的噪声和干扰功率的线性平均值”。 + +# 覆盖率 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009080953462.png) + +# NR和LTE的覆盖相关差异 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009081519659.png) + +# NR覆盖优化基础 + +## 覆盖优化的原则 + +1. 先优化SS-RSRP,后优化SS-SINR +2. 覆盖优化的两大关键任务:消除弱覆盖(保证SS-RSRP);净化切换带、消除交叉覆盖 +3. 优先优化弱覆盖、越区覆盖、再优化重叠覆盖 +4. 优先调整天线的下倾角、方位角、天线挂高和迁站及加站,最后考虑调整RS的发射功率和波束管理相关参数以及天线权值 + +# 覆盖优化整体流程 + +## 覆盖优化的流程 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009082637909.png) + +数据采集:通过不同的数据采集系统进行覆盖相关数据采集 + +数据分析:结合采集结果对数据进行综合分析,确定指标情况 + +原因分析:对存在覆盖问题的小区进行分析,并确定原因 + +方案制定:基于覆盖问题的原因,制定覆盖优化方案 + +方案实施:方案实施,并进行方案实施前后的评估 + +## 数据采集 + +覆盖指标的来源有哪些? + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009083312711.png) + +## 覆盖评估 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009083534560.png) + +## 覆盖类问题分析 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009083722471.png) + +## 覆盖问题原因 + +1. 故障问题 +2. 环境变化 +3. 新的需求 +4. 规划问题 +5. 施工问题 +6. 参数问题 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009083850079.png) + +### 故障问题 + +设备问题是指由于基站设备出现故障,导致无法提供服务,从而引起覆盖问题,一般表现为扫频仪或中断检测不到信号、信号弱等: + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009084029375.png) + +### 规划问题 + +规划问题也是影响覆盖问题的主要原因,规划偏差小的话可以通过优化解决,如果规划偏差大只能考虑新增站点,耗时耗力: + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009084421397.png) + +### 施工问题 + +施工问题,主要指在施工过程中没按照规划方案进行,如实际建设位置和规划位置有偏差、天馈基础参数设置和规划存在偏差等: + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009084831423.png) + +### 参数问题 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009085032588.png) + +### 无线环境 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009085143805.png) + +### 新增需求 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009085424820.png) + +## 覆盖优化的方案 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009085604425.png) + +# NR覆盖类问题及优化分析 + +## 覆盖类问题概述 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009085809348.png) + +## 弱覆盖问题分析 + +指标定义:弱覆盖是指在连片站点中间出现的完全没有NR信号的区域 + +UE终端的灵敏度一般为-124dBm,考虑部分商用终端与测试终端灵敏度的差异,预留5dB余量,覆盖空洞定义为RSRP < -119dBm的区域。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009090145488.png) + +## 弱覆盖原因及优化方案 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009090219993.png) + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009090355034.png) + +## 越区覆盖定义 + +所谓孤岛效应就是在无线通信系统中,因为复杂的无线环境,无线信号经过山脉、建筑物、以及大气层的发射、折射,或基站安装位置过高,以及波导效应等原因,弓|起在远离本小区覆盖的区域外形成-个强场区域,如图所示: + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009090536376.png) + +## 越区覆盖影响 + +由于这个区域超出其实际覆盖范围,往往这一-区域没有和周围小区配备邻区关系,形成孤岛,对A小区产生干扰,或在孤岛区域起呼的UE无法切换到A小区,产生掉话。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009090803666.png) + +## 越区覆盖原因及优化措施 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009090849864.png) + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009090956637.png) + +> **临时规避措施**:增加越区覆盖小区和主覆盖小区的单项邻区关系 + +## 重叠覆盖问题分析 + +**强导频**:RSRP > -90dBm + +**过多**:RSRP_number ≥ N,设定N=4 + +**无足够强主导频**:最强信号和第(N)个强信号强度的差值如果小于某一门限值D,即定义为该地点没有足够强主导频,RSRP(fist) -RSRP(N) ≤ D,设定D为-6dB + +**判断NR网络中的某点存在重叠覆盖的条件是**:RSRP > -90dB的小区个数大于等于4个;RSRP(fist) -RSRP(4) ≤ 6dB。当上述两个条件都满足时,即为重叠覆盖。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009091712704.png) + +## 重叠覆盖的影响及原因分析 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009091827593.png) + +## 重叠覆盖问题优化思路 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009091902716.png) + +## 覆盖不均衡 + +上下行覆盖不平衡:指目标覆盖区域内,上下行对称业务出现下行覆盖良好而上行覆盖受限或上行覆盖良好而下行覆盖受限的情况: + +> 上下行不平衡一-般是指下行覆盖大于上行覆盖,在只有下行覆盖的区域,当用户因为检测到了基站信号,想要接入或者切换时,因为上行达不到覆盖要求,也就是手机以最大功率发射基站也收不到,就会造成接入失败或切换失败。另外如果上行覆盖是连续的,那么下行信号因为覆盖大于.上行,会对邻区造成干扰。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009092135465.png) + +> 影响:上行覆盖不均衡常见表现为有信号但数据业务体验差,容易出现掉话、单通等感知类问题。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009092413897.png)![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image-20201009092540732.png) + diff --git a/source/_posts/C_basic.md b/source/_posts/C_basic.md new file mode 100644 index 0000000..c78f973 --- /dev/null +++ b/source/_posts/C_basic.md @@ -0,0 +1,495 @@ +--- +title: C语言复习笔记 +author: + name: 覃浩 + avatar: https://cdn.jsdelivr.net/gh/queen999/ImageHosting//imagesavatar.jpg + url: https://imqinhao.cn +categories: C语言 +date: 2020-12-15 20:13:14 +comments: true +--- + +第一章: + +- C语言的发展历史 +- C语言的特点及程序结构 + +第二章: + +- 标记 +- 类型 +- 运算符与表达式 + +第三章: + +- 编程小练习 + + + +# 第一章 + +## C语言程序的基本结构 + +- C语言程序是由函数构成的。一个C语言程序至少包含一个main函数。 + +- C语言程序总是从main函数开始执行。 + +- 为了增强程序的可读性,通常书写C语言程序时应遵循以下规则: + + > 一行内仅写一条语句 + > + > 正反大括号分别各占一行 + > + > 每对大括号上下对齐 + > + > 语句采用缩进格式,错落有致 + +- 每条语句的最后必须有一个分号,分号是C语句的组成部分。 + +- C语言本身没有输入/输出语句,输入/输出的操作由scanfprintf等函数来完成。 + +- 可以用/* ····· */ 或者 // ······· 在C语言程序中加注释,以增强程序的可读性。 + +## C语言程序的上机执行过程 + +编写好的C语言程序要经过编辑(输入)编译连接 后才能形成可执行的程序。 + +C语言程序的上机执行过程一般要经过四个步骤:编辑(Edit)编译(compile)连接(link)运行 。 + +![C程序上机执行过程](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/C%E7%A8%8B%E5%BA%8F%E4%B8%8A%E6%9C%BA%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6.png) + +### 编辑(Edit) + +编辑指源程序的输入,对应的文件称为源文件,其拓展名为".c"。 + +### 编译(compile) + +编译是使用编译器(compiler)将源文件转换为目标文件的过程。编译器对源程序进行语法检查,当发现错误时,将错误的类型和所在位置显示出来,以帮助程序员修改源程序中的错误。目标文件的扩展名为".obj"。 + +### 连接(link) + +连接是将目标文件和其他分别进行编译生成的目标文件(如果有的话)以及库函数连接生成可执行文件的过程。可执行文件的扩展名为".exe"。 + +### 运行 + +运行时将可执行文件投入运行,以获取程序处理的结果。如果程序运行结果不正确,则回到第一步,重新对程序进行编辑、编译、连接和运行。直到取得预期结果为止。 + +# 第二章 + +## 标记 + + + +> 标记(token)是具有唯一含义的语言的最小单位,分为五种:关键字(keyword)标识符(identifier)常量(constant)串字面量(string literal)以及标点符号(punctuator)。 + +### 关键字 + +关键字也称为保留字,C语言共有44个关键字: + +| auto | break | case | char | const | +| :------------- | :------------ | :----------------- | :---------------- | :----------- | +| **continue** | **default** | **do** | **double** | **else** | +| **enum** | **extern** | **float** | **for** | **goto** | +| **if** | **inline** | **int** | **long** | **register** | +| **restrict** | **return** | **short** | **signed** | **sizeof** | +| **static** | **struct** | **switch** | **typedef** | **union** | +| **unsigned** | **void** | **volatile** | **while** | **_Alignas** | +| **_Alignof** | **_Atomic** | **_Bool** | **_Complex** | **_Generic** | +| **_Imaginary** | **_Noreturn** | **_Static_assert** | **_Thread_local** | | + +### 标识符 + +标识符由小写字母大写字母数字下划线通用字符名实现定义的字符构成,且数字不能作为标识符的第一个字符关键字不能作为标识符。 + +C语言大小写敏感。 + +C语言对标识符的最大长度没有具体的限制,VC允许标识符的最大长度为247个字符。 + +通常,应该选择相应的英文单词或其缩写作为标识符,做到见名知义。 + +### 常量 + +> 在程序运行过程中,其值不变的量称为常量。常量分为四种类型。 + +--- + +#### 整数常量 + +整数常量只包括正整数和零,不包括负整数。 + +整数常量分为十进制整数常量八进制整数常量十六进制整数常量。 + +十进制整数常量由 0~9 组成,且以非零数字开头,如 123 、 1000 。 + +八进制整数常量由 0~7 组成,且以 0 开头,或者只有一个0,如 017 、 0 。 + +十六进制整数常量由 0~9 、A~F(或 a~f )组成,且以 0x 或 0X 开头,如0x1a 、 0XD5 。 + +```c +#include +int main(void) +{ + printf("sum = %d \n",123 + 012 + 0x12); + return 0; +} +``` + +--- + +#### 浮点常量 + +计算机中的浮点数只能近似地表示值在某个范围之内的有理数和一些特殊值,如NAN(非数值)、+INF(正无穷大)、-INF(负无穷大)等。 + +浮点常量是非负的浮点数,其十进制书写形式有以下两种: + +1. 小数点表示法 + +> 由数字 0 ~9 和小数点组成,必须有小数点。如果小数点左边为0,则 0 可省略;如果小数点右边为 0 ,则 0 可省略。 +> +> 例如: 5.20 520.0 520. 0.520 .520 0.0 0. .0 + +2. 指数表示法 + +> 第一种形式: +> +> ``` +> 十进制整数常量E符号位 十进制整数常量 +> ``` +> +> 第二种形式: +> +> ``` +> 浮点常量的小数表示法E符号位 十进制整数常量 +> ``` + +其中,E 也可以写成 e , “符号位” 即正负号是可选的。 + +--- + +#### 枚举常量 + +> 枚举常量是类型为 int 的标识符。 + +--- + +#### 字符常量 + +字符常量分为整数字符常量和宽字符常量。 + +```c +#include +int main(void) +{ + printf("%d %d %d %d\n", 'A' , 'b' + 2 , '0' , '1' + 3); + return 0; +} +``` + +> 分析 ASCII 码表,可以得出四条规则: +> +> (1)数字字符 0~9 的 ASCII 码值是连续递增的。 +> +> (2)大写字母 A~Z 的ASCII 码值是连续递增的。 +> +> (3)小写字母 a~z 的 ASCII 码值是连续递增的。 +> +> (4)大写字母的 ASCII 码比相应小写字母的 ASCII 码值小 32 。 + +| 转义序列 | 含义 | 十进制ASCII码值 | +| :------: | :-----------------------------------------------------: | :-------------: | +| \a | 响铃(alert) | 7 | +| \b | 退格(backspace) | 8 | +| \f | 走纸换页(form feed) | 12 | +| \n | 换行(new line),光标移到下一行的行首 | 10 | +| \r | 回车(carriage rerurn),光标移到当前行的行首 | 13 | +| \t | 水平制表(horizontal tab),光标移到当前行的下一个制表位 | 9 | +| \v | 垂直制表(verical tab) | 11 | + +### 串字面量 + +串字面量分为三种:字符串字面量UTF-8串字面量宽串字面量。 + +字符串字面量是用一对双引号括起来的零个或多个字符。在翻译的第七个阶段,空字符即'\0'被加到字符串字面量的末尾,然后字符串字面量以数组元素类型为 char 的数组的形式存储在内存中。 + +如果字符串字面中不含'\0',则该字符串字面量也称为字符串。 + +字符串的长度是指空字符前的字符在内存中所占的字节数。因此,长度为 n 的字符串,在内存中占 n+1 个字节。 + +不要将字符常量与字符串相混淆。例如,'z' 是字符常量,占 4 个字节;而 "z" 是字符串,占 2 个字节。 + +## 类型 + +类型分为两种: + +> 对象类型(object type):用于描述对象 +> +> 函数类型(function type):用于描述函数 + +### 基本类型 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B.png) + +### 枚举类型 + +一组命名的整数常量值构成枚举(enumeration),不同的枚举构成不同的枚举类型。 + +### 空类型 + +空类型的值的集合是空集,空类型是不完整对象类型,而且不可能是完整的。 + +### 派生类型 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/%E6%B4%BE%E7%94%9F%E7%B1%BB%E5%9E%8B.png) + +## 变量与常用类型说明符 + +### 变量 + +常用类型说明符有四种,分别是 int charfloatdouble 。 + +变量必须先声明后使用。 + +### 常用类型 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/%E5%B8%B8%E7%94%A8%E7%B1%BB%E5%9E%8B.png) + +在 0 ~ 2147483647 范围内的整数常量,其类型是 int 。 + +char 类型在输入时,两个数字字符之间不能加空格符,如果加了空格符,char 类型的变量获取的是空格符,而不是数字字符。 + +双精度浮点类型 double 比单精度浮点类型 float 精度更高,表示数据的范围更大。 + +浮点常量默认是 double 类型,在浮点常量后加后缀 f 或 F 则是 float 类型。 + +在没有特殊要求的情况下,程序设计中声明浮点常量,建议使用 double 类型。 + +## 运算符与表达式 + +### 表达式 + +表达式是由运算符和运算对象构成的序列。 + +表达式具有以下一个或多个功能: + +1. 描述一个值的计算 +2. 指定一个对象或一个函数 +3. 产生副作用 + +根据运算符的运算对象的数量,可将运算符分为以下三种: + +1. 单目运算符:只有一个运算对象 +2. 双目运算符:有两个运算对象 +3. 三目运算符:有三个运算对象 + +### 乘法类运算符 + +| 乘法运算符 | 除法运算符 | 模运算符 | +| :--------: | :--------: | :------: | +| * | / | % | + +乘法类运算符有三个,都是双目运算符。 + +### 加法类运算符 + +| 加法运算符 | 减法运算符 | +| :--------: | :--------: | +| + | - | + +加法类运算符有两个,都是双目运算符。 + +### sizeof运算符 + +>sizeof 运算符是单目运算符,表达式的值是运算对象所占用内存大小(按字节计算),其运算对象是表达式或用小括号括起来的类型名。 + + char 类型在内存中占 1 个字节。 + +int 类型在内存中占 4 个字节。 + +float 类型在内存中占 4 个字节。 + +double 类型在内存中占 8 个字节。 + +### 一元加运算符与一元减运算符 + +一元加运算符 + 是单目运算符,表达式的值是运算对象的值。 + +一元减运算符 - 是单目运算符,表达式的值是运算对象的相反数。 + +--- + +整数提权实例: + +```c +#include +int main(void) +{ + char ch; + printf("sizeof +ch = %d\n",sizeof +ch); + printf("sizeof ch = %d\n",sizeof ch); + printf("sizeof -ch = %d\n",sizeof -ch); + printf("sizeof ch = %d\n",sizeof ch); + return 0; +} +``` + +运行结果: + +``` +sizeof +ch = 4 +sizeof ch = 1 +sizeof -ch = 4 +sizeof ch = 1 +``` + +变量 ch 是 char 类型,在内存中占 1 个字节,整数提升将 ch 的值转换为 int 类型的值,因此,表达式 +ch 和 -ch 的类型都是 int ,在内存中占 4 个字节。 + +> 注意:变量 ch 的类型并没有改变,仍然是 char 类型。 + +### 常用算术转换 + +其中一个运算对象是 double 类型,另一个运算对象的值被转换为 double 类型的值。 + +如果以上条件不满足,并且其中一个运算对象是 float 类型,另一个运算对象的值被转换为 float 类型的值。 + +如果以上两个条件都不满足,对两个运算对象进行整数提升,即 char 类型运算对象的值被转换为 int 类型的值。 + +> 运算对象的类型并没有改变。 + +# 第三章 + +## 编程练习1 + +输入三个整数,求其平均值。 + +```c +#include +int main(void) +{ + // 输入三个整数,求其平均值 + int num1; + scanf("%d",&num1); + int num2; + scanf("%d",&num2); + int num3; + scanf("%d",&num3); + int average = (num1 + num2 + num3)/3; + printf("( %d + %d + %d) ÷ 3 = %d\n",num1,num2,num3,average); + return 0; +} +``` + +## 编程练习2 + +输入圆的半径,求圆的周长和面积。 + +```c +#include +int main(void) +{ + int r; + double PI = 3.14; + double c; + double s; + //用户输入半径 + scanf("%d",&r); + //圆的周长 + c = PI * (2 * r); + //圆的面积 + s = PI * (r * r); + //输出 + printf("圆的周长为:%.2lf,圆的面积为:%.2lf。\n",c,s); + return 0; +} +``` + +## 编程练习3 + +输入学生的相关信息:学号(int类型)、年龄(int类型)、性别(char 类型,'M'代表男生,'F'代表女生)和五门课程的成绩(double 类型);输出该学生的相关信息:学号、年龄、性别、各科成绩和平均成绩。 + +```c +#include +int main(void) +{ + // 输入学生的相关信息 + // 学号:int类型 + // 年龄:int类型 + // 性别:char类型(M:男生,N:女生) + // 五门课程的成绩:double类型 + + // 学号 + int id; + // 年龄 + int age; + // 性别 + char sex; + // 成绩1 + double score1; + // 成绩2 + double score2; + // 成绩3 + double score3; + // 成绩4 + double score4; + // 成绩5 + double score5; + // 获取输入信息 + printf("请输入学号:"); + scanf("%d",&id); + printf("请输入年龄:"); + scanf("%d",&age); + printf("请输入性别(男生:M 女生:F):"); + getchar(); + scanf("%c",&sex); + printf("请输入语文成绩:"); + scanf("%lf",&score1); + printf("请输入数学成绩:"); + scanf("%lf",&score2); + printf("请输入英语成绩:"); + scanf("%lf",&score3); + printf("请输入物理成绩:"); + scanf("%lf",&score4); + printf("请输入化学成绩:"); + scanf("%lf",&score5); + // 计算平均分 + double average = (score1 + score2 + score3 + score4 + score5) / 5; + // 输出成绩信息 + printf("学号\t\t年龄\t\t性别\t\t语文\t\t数学\t\t英语\t\t物理\t\t化学\t\t平均分\t\t\n"); + printf("%d\t\t%d\t\t%c\t\t%.1lf\t\t%.1lf\t\t%.1lf\t\t%.1lf\t\t%.1lf\t\t%.1lf\t\t\n",id,age,sex,score1,score2,score3,score4,score5,average); + return 0; +} +``` + +## 编程练习4 + +输入一个四位正整数,求其各位数字之和。例如:1357的各位数字之和为1 + 3 + 5 + 7 = 16 。 + +```c +#include +int main(void) +{ + // 输入一个四位正整数,求其各位数字之和。 + + int number; + // 获取用户输入 + scanf("%d",&number); + // 计算第一位数 + int num1 = number / 1000; + printf("第一位数是:%d\n",num1); + // 计算第二位数 + int num2 = number % 1000 / 100; + printf("第二位数是:%d\n",num2); + // 计算第三位数 + int num3 = number % (num1 * 1000 + num2 * 100) /10; + printf("第三位数是:%d\n",num3); + // 计算第四位数 + int num4 = number % (num1 * 1000 + num2 * 100 + num3 * 10); + printf("第四位数是:%d\n",num4); + + // 计算各个数字之和 + int result = num1 + num2 + num3 + num4; + printf("%d + %d + %d + %d = %d\n",num1,num2,num3,num4,result); + + return 0; +} +``` + diff --git a/source/_posts/Design_patterns_1.md b/source/_posts/Design_patterns_1.md new file mode 100644 index 0000000..8d67733 --- /dev/null +++ b/source/_posts/Design_patterns_1.md @@ -0,0 +1,558 @@ +--- +title: Java 设计模式-1 +author: + name: 覃浩 + avatar: https://cdn.jsdelivr.net/gh/queen999/ImageHosting//imagesavatar.jpg + url: https://www.zhengyuanyuan520.com +categories: Java +date: 2020-10-20 20:40:00 +comments: true +--- + +1.设计模式原则 + +2.设计模式分类 + +3.常用设计模式 + +4.工厂模式定义 + +5.工厂模式类图 + +6.工厂模式示例 + +7.工厂模式应用 + +8.抽象工厂模式定义 + +9.抽象工厂模式类图 + +10.抽象工厂模式示例 + +11.抽象工厂模式应用 + +12.工厂方法模式、抽象工厂模式区别 + + + + + +# 什么是设计模式 + +在软件工程中,设计模式是对软件设计中普遍存在的各种问题,所提出的解决方案。 + +换句话说,设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计的经验的总结。使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码可靠性。 + +# 设计模式原则 + +## 开闭原则 + +开闭原则的意思是:`对扩展开放,对修改封闭`。在程序需要进行扩展的时候,不能去修改或影响原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性更好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。 + +## 里氏代换原则 + +里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。里氏代换原则是继承复用的基石,只有当子类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而且子类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。 + +## 依赖倒转原则 + +这个原则是开闭原则的基础,核心内容:针对接口编程,高层模块不应该依赖底层模块,二者都应该依赖抽象而不依赖于具体。 + +## 接口隔离原则 + +这个原则的意思是:使用多个隔离的接口,比使用单个庞大的接口要好。其目的在于降低耦合度。由此可见,其实设计模式就是从大型软件架构出发,便于升级和维护软件的设计思想。它强调低依赖、低耦合。 + +## 单一职责原则 + +类的职责要单一,不能将太多的职责放在一个类中。 + +可能有的人会觉得单一职责原则和前面的接口隔离原则很相似,其实不然。其一,单一职责原则原注重的是职责;而接口隔离原则注重对接口依赖的隔离。其二,单一职责原则主要约束的是类,其次才是接口和方法,它针对的是程序中的实现和细节;而接口隔离原则主要约束接口,主要针对抽象,针对程序整体框架的构建。 + +## 最少知道原则 + +最少知道原则也叫迪米特法则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。 + +一个对象应该对其他对象保持最少的了解。类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。所以在类的设计上,每一个类都应当尽量降低成员的访问权限。 + +## 合成复用原则 + +合成复用原则就是在一个新的对象里通过关联关系(组合关系、聚合关系)来使用一些已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用功能的目的。简而言之,尽量多使用`组合/聚合`的方式,尽量少使用甚至不使用继承关系。 + +# 设计模式分类 + +通常来说设计模式分为三大类: + +- **创建型模式**,共 5 种:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。 +- **结构型模式**,共 7 种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 +- **行为型模式**,共 11 种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020190940.png) + +# 什么是工厂模式 + +> 工厂模式(Factory Pattern)的意义就跟它的名字一样,在面向对象程序设计中,工厂通常是一个用来创建其他对象的对象。工厂模式根据不同的参数来实现不同的分配方案和创建对象。 + +在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个`共同的接口`来指向新创建的对象。例如用工厂来创建 `人` 这个对象,如果我们需要一个男人对象,工厂就会为我们创建一个男人;如果我们需要一个女人,工厂就会为我们生产一个女人。 + +工厂模式通常分为: + +- 普通工厂模式 +- 多个工厂方法模式 +- 静态工厂方法模式 + +# 普通工厂模式 + +刚刚我们说到,用工厂模式来创建人。先创建一个男人,他每天都“吃饭、睡觉、打豆豆”,然后我们再创建一个女人,她每天也“吃饭、睡觉、打豆豆”。 + +我们以普通工厂模式为例,在 project 目录下新建一个`FactoryTest.java`。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020191237.png) + +```java +// 二者共同的接口 +interface Human{ + public void eat(); + public void sleep(); + public void beat(); +} + +// 创建实现类 Male +class Male implements Human{ + public void eat(){ + System.out.println("Male can eat."); + } + public void sleep(){ + System.out.println("Male can sleep."); + } + public void beat(){ + System.out.println("Male can beat."); + } +} +//创建实现类 Female +class Female implements Human{ + public void eat(){ + System.out.println("Female can eat."); + } + public void sleep(){ + System.out.println("Female can sleep."); + } + public void beat(){ + System.out.println("Female can beat."); + } +} + +// 创建普通工厂类 +class HumanFactory{ + public Human createHuman(String gender){ + if( gender.equals("male") ){ + return new Male(); + }else if( gender.equals("female")){ + return new Female(); + }else { + System.out.println("请输入正确的类型!"); + return null; + } + } +} + +// 工厂测试类 +public class FactoryTest { + public static void main(String[] args){ + HumanFactory factory = new HumanFactory(); + Human male = factory.createHuman("male"); + male.eat(); + male.sleep(); + male.beat(); + } +} +``` + +## 编译运行 + +```powershell +javac FactoryTest.java +java FactoryTest +``` + +## 运行结果 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020193135.png) + +# 多个工厂方法模式 + +普通工厂模式就是上面那样子了,那么多个工厂方法模式又有什么不同呢?在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象。多个工厂方法模式是提供多个工厂方法,分别创建对象。 + +```java +package 设计模式; + +//两者共同的接口 +interface Human { + public void eat(); + + public void sleep(); + + public void beat(); +} + +//创建实现类Male +class Male implements Human { + public void eat() { + System.out.println("Male can eat."); + } + + public void sleep() { + System.out.println("Male can sleep."); + } + + public void beat() { + System.out.println("Male can beat."); + } +} + +//创建实现类Female +class Female implements Human { + public void eat() { + System.out.println("Female can eat."); + } + + public void sleep() { + System.out.println("Female can sleep."); + } + + public void beat() { + System.out.println("Female can beat."); + } +} + +//多个工厂方法 +class HumanFactory { + public Male CreateMale() { + return new Male(); + } + + public Female createFemale() { + return new Female(); + } +} + +//工厂测试类 +public class FactoryTest2 { + public static void main(String args[]) { + HumanFactory factory = new HumanFactory(); + Human maleHuman = factory.CreateMale(); + maleHuman.eat(); + maleHuman.sleep(); + maleHuman.beat(); + } +} +``` + +## 编译运行 + +``` +javac FactoryTest2.java +java FactoryTest2 +``` + +## 运行结果 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020194538.png) + +# 静态工厂方法模式 + +将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。 + +```java +package 设计模式; + +//两者共同的接口 +interface Human { + public void eat(); + + public void sleep(); + + public void beat(); +} + +//创建实现类Male +class Male implements Human { + public void eat() { + System.out.println("Male can eat."); + } + + public void sleep() { + System.out.println("Male can sleep."); + } + + public void beat() { + System.out.println("Male can beat."); + } +} + +//创建实现类Female +class Female implements Human { + public void eat() { + System.out.println("Female can eat."); + } + + public void sleep() { + System.out.println("Female can sleep."); + } + + public void beat() { + System.out.println("Female can beat."); + } +} + +//多个工厂方法 +class HumanFactory{ + public static Male createMale() { + return new Male(); + } + public static Female createFemale() { + return new Female(); + } +} + +//工厂测试类 +public class FactoryTest2 { + public static void main(String[] args){ + Human male = HumanFactory.createMale(); + male.eat(); + male.sleep(); + male.beat(); + } +} +``` + +总结:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。 + +# 什么是抽象工厂模式 + +抽象工厂模式(Abstract Factory Pattern)是一种软件开发设计模式。抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。如果比较抽象工厂模式和工厂模式,我们不难发现前者只是在工厂模式之上增加了一层抽象的概念。抽象工厂是一个父类工厂,可以创建其它工厂类。所以我们也叫它 “工厂的工厂”。 + +# 抽象工厂模式类图 + +“女娲娘娘”只有一个,而我们的工厂却可以有多个,因此在这里用作例子就不合适了。作为“女娲娘娘”生产出来的男人女人们,那就让我们来当一次吃货吧。(吃的东西总可以任性多来一点) + +现在,假设我们有 A、B 两个厨房。每个厨房拥有的餐具和食品都不一样,但是用户搭配使用的方式,比如刀子和苹果、杯子和牛奶等等,我们假设是一致的。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020200923.png) + +```java +package 抽象工厂模式; + +//抽象食物 +interface Food{ + public String getFoodName(); +} + +//抽象餐具 +interface TableWare{ + public String getToolName(); +} +//抽象工厂 +interface KitchenFactory{ + public Food getFood(); + public TableWare getTableWare(); +} + +//具体食物 Apple 的定义如下 +class Apple implements Food{ + @Override + public String getFoodName() { + return "apple"; + } +} + +//具体餐具 Knife 的定义如下 +class Knife implements TableWare{ + @Override + public String getToolName() { + return "knife"; + } +} + +//以具体工厂 AKitchen 为例 +class AKitchen implements KitchenFactory{ + @Override + public Food getFood() { + return new Apple(); + } + @Override + public TableWare getTableWare() { + return new Knife(); + } +} + +//吃货要开吃了 +public class Foodaholic { + public void eat(KitchenFactory kitchenFactory) { + System.out.println("A foodaholic is eating " + kitchenFactory.getFood().getFoodName() + " with " + kitchenFactory.getTableWare().getToolName()); + } + + public static void main(String[] args) { + Foodaholic foodaholic = new Foodaholic(); + KitchenFactory kitchenFactory = new AKitchen(); + foodaholic.eat(kitchenFactory); + + } + +} +``` + +## 编译运行 + +``` +javac Foodaholic.java +java Foodaholic +``` + +## 运行结果 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020203200.png) + +抽象工厂模式特别适合于这样的一种产品结构:产品分为几个系列,在每个系列中,产品的布局都是类似的,在一个系列中某个位置的产品,在另一个系列中一定有一个对应的产品。这样的产品结构是存在的,这几个系列中同一位置的产品可能是互斥的,它们是针对不同客户的解决方案,每个客户都只选择其一。 + +# 工厂方法模式、抽象工厂模式区别 + +工厂方法模式、抽象工厂模式,傻傻分不清楚。 + +为了解释得更清楚,先介绍两个概念: + +- **产品等级结构**:比如一个抽象类是食物,其子类有苹果、牛奶等等,则抽象食物与具体食物名称之间构成了一个产品等级结构。食物是抽象的父类,而具体的食物名称是其子类。 +- **产品族**:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。如 AKitchen 生产的苹果、刀子,苹果属于食物产品等级结构中,而刀子则属于餐具产品等级结构中。而 BKitchen 可能生成另一组产品,如牛奶、杯子。 + +因此工厂方法模式、抽象工厂模式最大的区别在于: + +工厂方法模式:针对的是 **一个产品等级结构**。 + +抽象工厂模式:针对 **多个产品等级结构**。 + +# 什么是适配器模式 + +顾名思义,适配器模式(Adapter Pattern)当然是用来适配的啦。当你想使用一个已有的类,但是这个类的接口跟你的又不一样,不能拿来直接用,这个时候你就需要一个适配器来帮你了。 + +这就好像你兴冲冲地跑去香港,买了个港版的 iPhone6,充电器插头拿回家一看,不能用啊。这时候你多么需要买一个转接头适配器... + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020223507.png) + +你去香港旅游,买的 iPhone6 的充电器插头是英标的,它是那种三脚是方形的插头。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020223608.png) + +而咱们国标的插头是两只脚,即使是三只脚的插头也和英标不一样。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020223722.png) + +为了方便,这里我们就假设国标插头就只是两只脚的插头吧。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020223745.png) + +好的,目标明确,英标三只脚插头充电,国标两只脚插头充电。你家很富,有很多插座可以充电。 + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201020223805.png) + +在国内的家中只能用国标接口进行充电。 + +```java + +// 国标插头 +public interface CnPluginInterface { + void chargeWith2Pins(); +} + +// 实现国标插座的充电方法 +public class CnPlugin implements CnPluginInterface { + public void chargeWith2Pins() { + System.out.println("charge with CnPlugin"); + } +} + +// 在国内家中充电 +public class Home { + private CnPluginInterface cnPlugin; + + public Home() { } + + public Home(CnPluginInterface cnPlugin) { + this.cnPlugin = cnPlugin; + } + + public void setPlugin(CnPluginInterface cnPlugin) { + this.cnPlugin = cnPlugin; + } + + // 充电 + public void charge() { + // 国标充电 + cnPlugin.chargeWith2Pins(); + } +} + +// 国标测试类 +public class CnTest { + public static void main(String[] args) { + CnPluginInterface cnPlugin = new CnPlugin(); + Home home = new Home(cnPlugin); + // 会输出 “charge with CnPlugin” + home.charge(); + } +} +``` + +然而,当把 iPhone6 带回来时,因为与家里的插座不匹配,所以需要一个适配器。这个适配器必须满足以下条件: + +> 1. 插头必须符合国内标准的接口,否则的话还是没办法插到国内插座中。 +> 2. 在调用上面实现的国标接口进行充电时,提供一种机制,将这个调用转到对英标接口的调用 。 + +这就要求: + +> 1. 适配器必须实现原有的旧的接口。 +> 2. 适配器对象中持有对新接口的引用,当调用旧接口时,将这个调用委托给实现新接口的对象来处理,也就是在适配器对象中组合一个新接口。 + +```java +// 英标插头 +public interface EnPluginInterface { + void chargeWith3Pins(); +} + +// 实现英标插座的充电方法 +public class EnPlugin implements EnPluginInterface { + public void chargeWith3Pins() { + System.out.println("charge with EnPlugin"); + } +} + +//适配器 +public class PluginAdapter implements CnPluginInterface { + private EnPluginInterface enPlugin; + + public PluginAdapter(EnPluginInterface enPlugin) { + this.enPlugin = enPlugin; + } + + // 这是重点,适配器实现了国标的插头,然后重写国标的充电方法,在国标的充电方法中调用英标的充电方法 + @Override +public void chargeWith2Pins() { + enPlugin.chargeWith3Pins(); + } +} + +// 适配器测试类 +public class AdapterTest { + public static void main(String[] args) { + EnPluginInterface enPlugin = new EnPlugin(); + Home home = new Home(); + PluginAdapter pluginAdapter = new PluginAdapter(enPlugin); + home.setPlugin(pluginAdapter); + // 会输出 “charge with EnPlugin” + home.charge(); + } +} +``` + +# 适配器模式的三个特点 + +- 适配器对象实现原有接口 +- 适配器对象组合一个实现新接口的对象(这个对象也可以不实现一个接口,只是一个单纯的对象) +- 对适配器原有接口方法的调用被委托给新接口的实例的特定方法 \ No newline at end of file diff --git a/source/_posts/Files_and_directories.md b/source/_posts/Files_and_directories.md index 7d4a28b..a400407 100644 --- a/source/_posts/Files_and_directories.md +++ b/source/_posts/Files_and_directories.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Linux date: 2020-08-13 20:13:14 -music: - type: song - id: 1460682363 comments: true --- diff --git a/source/_posts/FixedTools.md b/source/_posts/FixedTools.md index 40b694c..0eebd0d 100644 --- a/source/_posts/FixedTools.md +++ b/source/_posts/FixedTools.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Photoshop date: 2020-03-29 14:37:11 -music: - type: song - id: 1398663411 comments: true tags: - 图像处理 diff --git a/source/_posts/GRE-VPN.md b/source/_posts/GRE-VPN.md index b238800..63ebaee 100644 --- a/source/_posts/GRE-VPN.md +++ b/source/_posts/GRE-VPN.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 网络安全 date: 2020-03-21 11:30:11 -music: - type: song - id: 27890395 comments: true tags: - 网络安全 diff --git a/source/_posts/GRE-over-IPSec.md b/source/_posts/GRE-over-IPSec.md index dda80e4..1816556 100644 --- a/source/_posts/GRE-over-IPSec.md +++ b/source/_posts/GRE-over-IPSec.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 网络安全 date: 2020-03-30 16:30:11 -music: - type: song - id: 1411358329 comments: true tags: - 网络安全 diff --git a/source/_posts/GSM.md b/source/_posts/GSM.md index fab32f7..053c9d2 100644 --- a/source/_posts/GSM.md +++ b/source/_posts/GSM.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-03-07 10:00:00 -music: - type: song - id: 233974 comments: true tags: - 通信技术 diff --git a/source/_posts/ICIC.md b/source/_posts/ICIC.md index 6df63c7..0c3a872 100644 --- a/source/_posts/ICIC.md +++ b/source/_posts/ICIC.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-05-12 14:11:21 -music: - type: song - id: 1436709403 comments: true tags: - 通信技术 diff --git a/source/_posts/IPSec_VPN.md b/source/_posts/IPSec_VPN.md index b052391..1ba16ae 100644 --- a/source/_posts/IPSec_VPN.md +++ b/source/_posts/IPSec_VPN.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 网络安全 date: 2020-03-25 12:30:11 -music: - type: song - id: 1424520099 comments: true tags: - 网络安全 diff --git a/source/_posts/IP_Bearer_Network_basic.md b/source/_posts/IP_Bearer_Network_basic.md index d735f10..72a5ec9 100644 --- a/source/_posts/IP_Bearer_Network_basic.md +++ b/source/_posts/IP_Bearer_Network_basic.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-03-07 16:00:00 -music: - type: song - id: 1320098098 comments: true tags: - 通信技术 diff --git a/source/_posts/LTE.md b/source/_posts/LTE.md index 866c877..f6d5288 100644 --- a/source/_posts/LTE.md +++ b/source/_posts/LTE.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-03-07 12:25:00 -music: - type: song - id: 531295576 comments: true tags: - 通信技术 diff --git a/source/_posts/Layer.md b/source/_posts/Layer.md index 073e0bf..9c21041 100644 --- a/source/_posts/Layer.md +++ b/source/_posts/Layer.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Photoshop date: 2020-04-03 14:00:00 -music: - type: song - id: 545350938 comments: true tags: - 图像处理 diff --git a/source/_posts/Linux_often_use.md b/source/_posts/Linux_often_use.md index b9c670c..7f19168 100644 --- a/source/_posts/Linux_often_use.md +++ b/source/_posts/Linux_often_use.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Linux date: 2020-03-11 13:04:14 -music: - type: song - id: 108493 comments: true keywords: Linux操作 description: diff --git a/source/_posts/MIMO.md b/source/_posts/MIMO.md index ef776ea..c5ac4e3 100644 --- a/source/_posts/MIMO.md +++ b/source/_posts/MIMO.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-05-11 21:21:21 -music: - type: song - id: 1433434738 comments: true mathjax: true tags: diff --git a/source/_posts/MySQL8_basics.md b/source/_posts/MySQL8_basics.md index fa9b2a6..969f01d 100644 --- a/source/_posts/MySQL8_basics.md +++ b/source/_posts/MySQL8_basics.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 数据库 date: 2020-02-27 12:50:11 -music: - type: song - id: 1407551413 comments: true tags: - 数据库 diff --git a/source/_posts/NB-IoT.md b/source/_posts/NB-IoT.md index 55343f5..7a7717c 100644 --- a/source/_posts/NB-IoT.md +++ b/source/_posts/NB-IoT.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-03-07 15:00:00 -music: - type: song - id: 1328146041 comments: true tags: - 通信技术 diff --git a/source/_posts/Network_Access.md b/source/_posts/Network_Access.md index 9784418..c0fb91f 100644 --- a/source/_posts/Network_Access.md +++ b/source/_posts/Network_Access.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 计算机三级 date: 2020-04-24 18:48:12 -music: - type: song - id: 1370047789 comments: true tags: - 网络技术 diff --git a/source/_posts/No-module-named-pip.md b/source/_posts/No-module-named-pip.md index 4dfc443..880e292 100644 --- a/source/_posts/No-module-named-pip.md +++ b/source/_posts/No-module-named-pip.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Python date: 2020-05-19 21:10:00 -music: - type: song - id: 165364 comments: true --- diff --git a/source/_posts/OFDMA.md b/source/_posts/OFDMA.md index f69de56..43d9d38 100644 --- a/source/_posts/OFDMA.md +++ b/source/_posts/OFDMA.md @@ -6,11 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-04-25 17:13:00 -music: - enable: true - server: netease - type: song - id: 174963 comments: true mathjax: true tags: diff --git a/source/_posts/OLT_command.md b/source/_posts/OLT_command.md index 5b568f1..bbef7b6 100644 --- a/source/_posts/OLT_command.md +++ b/source/_posts/OLT_command.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 交换机 date: 2020-02-27 12:13:14 -music: - type: song - id: 554241732 comments: true tags: 交换机 keywords: 交换机 diff --git a/source/_posts/Python-3.md b/source/_posts/Python-3.md index e0b4fce..5866e85 100644 --- a/source/_posts/Python-3.md +++ b/source/_posts/Python-3.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Python date: 2020-05-24 11:11:11 -music: - type: song - id: 509728841 comments: true --- diff --git a/source/_posts/Python-4.md b/source/_posts/Python-4.md index 6fe81e1..1f80f3b 100644 --- a/source/_posts/Python-4.md +++ b/source/_posts/Python-4.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Python date: 2020-05-25 11:11:11 -music: - type: song - id: 36990266 comments: true --- diff --git a/source/_posts/Python-5.md b/source/_posts/Python-5.md index 422fd0f..ff55950 100644 --- a/source/_posts/Python-5.md +++ b/source/_posts/Python-5.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Python date: 2020-06-01 13:14:20 -music: - type: song - id: 1351520305 comments: true --- diff --git a/source/_posts/Python_basic_(1).md b/source/_posts/Python_basic_(1).md index 59e5377..9177814 100644 --- a/source/_posts/Python_basic_(1).md +++ b/source/_posts/Python_basic_(1).md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Python date: 2020-03-11 19:04:14 -music: - type: song - id: 440353010 comments: true keywords: - Python diff --git a/source/_posts/Python_cards_manage.md b/source/_posts/Python_cards_manage.md index e4caaf1..f28ce3f 100644 --- a/source/_posts/Python_cards_manage.md +++ b/source/_posts/Python_cards_manage.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Python date: 2020-07-07 17:20:14 -music: - type: song - id: 1449213110 comments: true --- diff --git a/source/_posts/Python_variable.md b/source/_posts/Python_variable.md index cb0a1bd..96ec42f 100644 --- a/source/_posts/Python_variable.md +++ b/source/_posts/Python_variable.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Python date: 2020-07-07 18:30:11 -music: - type: song - id: 1352968308 comments: true --- diff --git a/source/_posts/RedHat_setup_script.md b/source/_posts/RedHat_setup_script.md index 61e22cc..fc33b7b 100644 --- a/source/_posts/RedHat_setup_script.md +++ b/source/_posts/RedHat_setup_script.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Linux date: 2020-02-14 20:13:14 -music: - type: song - id: 208902 comments: true tags: 系统安装 keywords: Linux安装 diff --git a/source/_posts/TD-LTE-System.md b/source/_posts/TD-LTE-System.md index 4c56599..1915ac3 100644 --- a/source/_posts/TD-LTE-System.md +++ b/source/_posts/TD-LTE-System.md @@ -6,11 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-04-20 20:11:00 -music: - enable: true - server: netease - type: song - id: 108245 comments: true mathjax: true tags: diff --git a/source/_posts/Web_site_SSL.md b/source/_posts/Web_site_SSL.md index 347cfb0..a6e1cf8 100644 --- a/source/_posts/Web_site_SSL.md +++ b/source/_posts/Web_site_SSL.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 服务器 date: 2020-02-15 19:29:30 -music: - type: song - id: 1357825630 comments: true tags: - 软考 diff --git a/source/_posts/Windows_Web_build_environment.md b/source/_posts/Windows_Web_build_environment.md index 3781ab1..2e48c13 100644 --- a/source/_posts/Windows_Web_build_environment.md +++ b/source/_posts/Windows_Web_build_environment.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 服务器 date: 2020-02-14 21:21:21 -music: - type: song - id: 36270426 comments: true tags: - 软考 diff --git a/source/_posts/Windows_Web_build_website.md b/source/_posts/Windows_Web_build_website.md index 69e8c96..1501c57 100644 --- a/source/_posts/Windows_Web_build_website.md +++ b/source/_posts/Windows_Web_build_website.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 服务器 date: 2020-02-14 22:22:22 -music: - type: song - id: 1372796676 comments: true tags: - 软考 diff --git a/source/_posts/Windows_Web_often_use.md b/source/_posts/Windows_Web_often_use.md index 517426d..864a42d 100644 --- a/source/_posts/Windows_Web_often_use.md +++ b/source/_posts/Windows_Web_often_use.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 服务器 date: 2020-02-15 14:23:30 -music: - type: song - id: 514761281 comments: true tags: - 软考 diff --git a/source/_posts/a_server_build_many_webs.md b/source/_posts/a_server_build_many_webs.md index 6f1f9bc..b680828 100644 --- a/source/_posts/a_server_build_many_webs.md +++ b/source/_posts/a_server_build_many_webs.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 服务器 date: 2020-02-15 16:45:30 -music: - type: song - id: 1382596189 comments: true tags: - 软考 diff --git a/source/_posts/acl.md b/source/_posts/acl.md index 8a7e76f..2e875e4 100644 --- a/source/_posts/acl.md +++ b/source/_posts/acl.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 网络安全 date: 2020-03-04 12:30:11 -music: - type: song - id: 1376142151 comments: true tags: - 网络安全 diff --git a/source/_posts/bitwarden.md b/source/_posts/bitwarden.md index 6052361..7f15c06 100644 --- a/source/_posts/bitwarden.md +++ b/source/_posts/bitwarden.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Linux date: 2020-03-31 13:04:14 -music: - type: song - id: 298213 comments: true --- diff --git a/source/_posts/build-MAN-idea.md b/source/_posts/build-MAN-idea.md index 0e7ddfe..97e3471 100644 --- a/source/_posts/build-MAN-idea.md +++ b/source/_posts/build-MAN-idea.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 计算机三级 date: 2020-04-24 12:12:12 -music: - type: song - id: 1440410293 comments: true tags: - 网络技术 diff --git a/source/_posts/color.md b/source/_posts/color.md index e9a38eb..3e4c595 100644 --- a/source/_posts/color.md +++ b/source/_posts/color.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Photoshop date: 2020-04-04 13:06:11 -music: - type: song - id: 1404906595 comments: true tags: - 图像处理 diff --git a/source/_posts/computer_Internet_1.md b/source/_posts/computer_Internet_1.md index d857ff9..0ee57fa 100644 --- a/source/_posts/computer_Internet_1.md +++ b/source/_posts/computer_Internet_1.md @@ -7,9 +7,6 @@ author: categories: 计算机网络 mathjax: true date: 2020-07-17 18:25:00 -music: - type: song - id: 493735012 comments: true --- diff --git a/source/_posts/computer_network_basics.md b/source/_posts/computer_network_basics.md index 57ac6b0..e1d0909 100644 --- a/source/_posts/computer_network_basics.md +++ b/source/_posts/computer_network_basics.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 计算机网络 date: 2020-02-27 13:14:20 -music: - type: song - id: 1410666632 comments: true tags: - 基础网络 diff --git a/source/_posts/free-get-189vip.md b/source/_posts/free-get-189vip.md index f1c46b6..8099df4 100644 --- a/source/_posts/free-get-189vip.md +++ b/source/_posts/free-get-189vip.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 小技巧 date: 2020-05-23 12:00:00 -music: - type: song - id: 1424520099 comments: true --- diff --git a/source/_posts/hello.md b/source/_posts/hello.md deleted file mode 100644 index 96e9205..0000000 --- a/source/_posts/hello.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: 博客开通 -author: - name: 覃浩 - avatar: https://cdn.jsdelivr.net/gh/queen999/ImageHosting//imagesavatar.jpg - url: https://www.zhengyuanyuan520.com -categories: 个人 -music: - type: song - id: 1381755293 -date: 2019-12-04 13:14:20 -comments: true -keywords: 博客 -description: -photos: https://zhengyuanyuan520.cn/images/background.jpg ---- -博客搭建完成啦,欢迎大家访问! \ No newline at end of file diff --git a/source/_posts/huawei-PCManager.md b/source/_posts/huawei-PCManager.md index e513eb1..60feb51 100644 --- a/source/_posts/huawei-PCManager.md +++ b/source/_posts/huawei-PCManager.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 软件破解 date: 2020-05-19 11:42:14 -music: - type: song - id: 1425626819 comments: true --- diff --git a/source/_posts/huawei-exam-application.md b/source/_posts/huawei-exam-application.md index 6cae0ed..28d3071 100644 --- a/source/_posts/huawei-exam-application.md +++ b/source/_posts/huawei-exam-application.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 华为认证 date: 2020-05-29 20:13:14 -music: - type: song - id: 1351520305 comments: true --- diff --git a/source/_posts/lanzous.md b/source/_posts/lanzous.md index 2e6bb82..77f53a1 100644 --- a/source/_posts/lanzous.md +++ b/source/_posts/lanzous.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 小技巧 date: 2020-06-11 20:20:11 -music: - type: song - id: 33206214 comments: true --- diff --git a/source/_posts/linux.md b/source/_posts/linux.md new file mode 100644 index 0000000..525aa41 --- /dev/null +++ b/source/_posts/linux.md @@ -0,0 +1,102 @@ +--- +title: TCP/IP简介 +author: + name: 覃浩 + avatar: https://cdn.jsdelivr.net/gh/queen999/ImageHosting//imagesavatar.jpg + url: https://www.zhengyuanyuan520.com +categories: 计算机网络 +date: 2020-10-05 13:14:14 +comments: true +--- + +知识点 + +- IP 地址 +- 域名 +- MAC 地址 +- 端口号 +- 封装和分用 + + + +提到网络协议栈结构,最著名的当属 OSI 七层模型,但是 TCP/IP 协议族的结构则稍有不同,它们之间的层次结构有如图对应关系: + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/1548669082626.png) + +可见 TCP/IP 被分为 4 层,每层承担的任务不一样,各层的协议的工作方式也不一样,每层封装上层数据的方式也不一样: + +- 应用层:应用程序通过这一层访问网络,常见 FTP、HTTP、DNS 和 TELNET 协议; +- 传输层:TCP 协议和 UDP 协议; +- 网络层:IP 协议,ARP、RARP 协议,ICMP 协议等; +- 网络接口层:是 TCP/IP 协议的基层,负责数据帧的发送和接收。 + +> TCP/IP(Transmission Control Protocol/Internet Protocol)是传输控制协议和网络协议的简称,它定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。 +> +> TCP/IP 不是一个协议,而是一个协议族的统称,里面包括了 IP 协议、ICMP 协议、TCP 协议、以及 http、ftp、pop3 协议等。网络中的计算机都采用这套协议族进行互联。 + +# IP地址 + +网络上每一个节点都必须有一个独立的 IP 地址,通常使用的 IP 地址是一个 32bit 的数字,被 `.` 分成 4 组,例如,`255.255.255.255` 就是一个 IP 地址。有了 IP 地址,用户的计算机就可以发现并连接互联网中的另外一台计算机。 + +在 终端输入 `ifconfig -a` 命令查看自己的 IP 地址: + +```shell +ifconfig -a +``` + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/61acdc3e0704fdf5fb97876dec817ff3-0) + +# 域名 + +用 12 位数字组成的 IP 地址很难记忆,在实际应用时,用户一般不需要记住 IP 地址,互联网给每个 IP 地址起了一个别名,习惯上称作域名。 + +域名与计算机的 IP 地址相对应,并把这种对应关系存储在域名服务系统 DNS(Domain Name System) 中,这样用户只需记住域名就可以与指定的计算机进行通信了。 + +常见的域名包括 com、net 和 org 三种顶级域名后缀,除此之外每个国家还有自己国家专属的域名后缀(比如我国的域名后缀为 cn)。目前经常使用的域名诸如百度([www.baidu.com](https://www.baidu.com/))、Linux 组织([www.lwn.net](https://lwn.net/))等等。 + +我们可以使用命令 `nslookup` 或者 `ping` 来查看与域名相对应的 IP 地址,由于实验楼网络限制,我们可以使用 `ping github.com`(如果 `github` 也 ping 不通,那么可以使用 `ping labfile.oss.aliyuncs.com`,如果你是会员账户,那么也可以 ping 其他的域名)查看。 + +例如: + +![](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/20201016215115.png) + +# MAC地址 + +MAC(Media Access Control)地址,或称为物理地址、硬件地址,用来定义互联网中设备的位置。 + +在 TCP/IP 层次模型中,网络层管理 IP 地址,链路层则负责 MAC 地址。因此每个网络位置会有一个专属于它的 IP 地址,而每个主机会有一个专属于它 MAC 地址。 + +# 端口号 + +IP 地址是用来发现和查找网络中的地址,但是不同程序如何互相通信呢?这就需要端口号来识别了。如果把 IP 地址比作一间房子,端口就是出入这间房子的门。真正的房子只有几个门,但是端口采用 16 比特的端口号标识,一个 IP 地址的端口可以有 65536(即:216)个之多! + +服务器的默认程序一般都是通过人们所熟知的端口号来识别的。例如,对于每个 TCP/IP 实现来说,SMTP(简单邮件传输协议)服务器的 TCP 端口号都是 `25`,FTP(文件传输协议)服务器的 TCP 端口号都是 `21`,TFTP(简单文件传输协议)服务器的 UDP 端口号都是 `69`。任何 TCP/IP 实现所提供的服务都用众所周知的 `1-1023` 之间的端口号。这些人们所熟知的端口号由 Internet 端口号分配机构(Internet Assigned Numbers Authority,IANA)来管理。 + +常用协议对应端口号: + +- SSH 22 +- FTP 20 和 21 +- Telnet 23 +- SMTP 25 +- TFTP 69 +- HTTP 80 +- SNMP 161 +- Ping 使用 ICMP,无具体端口号 + +# 封装和分用 + +**封装**:当应用程序发送数据的时候,数据在协议层次当中自顶向下通过每一层,每一层都会对数据增加一些首部或尾部信息,这样的信息称之为协议数据单元(Protocol Data Unit,缩写为 PDU),在分层协议系统里,在指定的协议层上传送的数据单元,包含了该层的协议控制信息和用户信息。如下图所示: + +- 物理层(一层)PDU 指数据位(Bit) +- 数据链路层(二层)PDU 指数据帧(Frame) +- 网络层(三层)PDU 指数据包(Packet) +- 传输层(四层)PDU 指数据段(Segment) +- 第五层以上为数据(data) + +![](https://dn-simplecloud.shiyanlou.com/uid/8797/1548670748600.png) + +**分用**:当主机收到一个数据帧时,数据就从协议层底向上升,通过每一层时,检查并去掉对应层次的报文首部或尾部,与封装过程正好相反。 + +# RFC + +RFC(Request for Comment)文档是所有以太网协议的正式标准,并在其官网上面公布,由 IETF 标准协会制定。大量的 RFC 并不是正式的标准,出版的目的只是为了提供信息。RFC 的篇幅不一,从几页到几百页不等。每一种协议都用一个数字来标识,如 RFC 3720 是 iSCSI 协议的标准,数字越大意味着 RFC 的内容越新或者是对应的协议(标准)出现的比较晚。 \ No newline at end of file diff --git a/source/_posts/manage-MAN-skill.md b/source/_posts/manage-MAN-skill.md index 939c6f4..aa708fd 100644 --- a/source/_posts/manage-MAN-skill.md +++ b/source/_posts/manage-MAN-skill.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 计算机三级 date: 2020-04-13 19:46:11 -music: - type: song - id: 1405283464 comments: true tags: - 网络技术 diff --git a/source/_posts/mobile_communication.md b/source/_posts/mobile_communication.md index 377a598..3714798 100644 --- a/source/_posts/mobile_communication.md +++ b/source/_posts/mobile_communication.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-03-06 13:30:11 -music: - type: song - id: 553815178 comments: true tags: - 通信技术 diff --git a/source/_posts/mysql-install.md b/source/_posts/mysql-install.md index 0e1f9dd..af9d311 100644 --- a/source/_posts/mysql-install.md +++ b/source/_posts/mysql-install.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 数据库 date: 2020-06-13 12:00:00 -music: - type: song - id: 1425626819 comments: true --- diff --git a/source/_posts/network_security_comprehensive.md b/source/_posts/network_security_comprehensive.md new file mode 100644 index 0000000..bc9028c --- /dev/null +++ b/source/_posts/network_security_comprehensive.md @@ -0,0 +1,509 @@ +--- +title: 《网络设备安全配置与管理》综合实训任务书 +author: + name: 覃浩 + avatar: https://cdn.jsdelivr.net/gh/queen999/ImageHosting//imagesavatar.jpg + url: https://www.zhengyuanyuan520.com +categories: 网络安全 +date: 2020-11-1 16:30:11 +comments: true +--- + +1. **网络搭建** + +根据所给定的拓扑要求,将给定的网络设备互连,搭建物理网络。 + +**2. IP 地址规划** + +根据要求确定所需子网的数量,每个子网的主机数量,设计适当的编址方案,填写网络地址规划表和设备地址表。 + +**3. 网络设备的安全配置** + +根据任务书中指出的安全需求,完成数据网络安全配置。 + +**4 数据网络安全测试** + +安全配置后进行完全效果测试,并分析对应的数据包,理解背后的原理。 + + + +# **一、综合实训内容描述** + +《网络设备安全配置与管理》综合实训目的在于通过实际案例需求分析完成设备的仿真配置,同时根据需求完成网络安全配置与管理,保证数据网络安全正常运行。从而能在实际工程中理解网络安全通信的含义。 + +# **二、实施中需要完成的工作任务** + +**1. ** **网络搭建** + +根据所给定的拓扑要求,将给定的网络设备互连,搭建物理网络。 + +**2. IP** **地址规划** + +根据要求确定所需子网的数量,每个子网的主机数量,设计适当的编址方案,填写网络地址规划表和设备地址表。 + +**3.** **网络设备的安全配置** + +根据任务书中指出的安全需求,完成数据网络安全配置。 + +**4** **数据网络安全测试** + +安全配置后进行完全效果测试,并分析对应的数据包,理解背后的原理。 + +# **三、注意事项** + +项目完成后需要提交相关的WORD规划文件以及相应的配置文档。两份文档存储在文件夹中上交。文件及文件夹命名规则如下: + +| 文档类型 | 格式 | 名称 | +| ---------- | ---- | ---------------------- | +| 规划表文档 | WORD | 综合实训任务书(姓名) | +| 配置文档 | PKT | 综合实训项目(姓名) | + + + + + +# **四、网络拓扑图如下** + +![image001](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image001.png) + +# **五、根据网络安全需求,进行网络安全配置** + +(一)基础配置 + +1、在Packet Tracer中绘制如图所示拓扑图,模拟某公司分隔两地的总公司和分公司之间通过Internet 连接。(注意:XX为学号最后2位) + +2、IP地址规划和配置 + +(1)IP地址规划: + +如拓扑图所示,2个分公司内部采用私网地址,Internet采用公网地址,地址表规划如下: + +| **设备名称** | **接口** | **IP** **地址** | **网关** | +| ------------ | -------------- | ----------------- | ----------------- | +| R1 | Fa0/0 | 10.10.11.254/24 | | +| Fa1/0 | 100.1.1.1/30 | | | +| tunnel | 1.1.1.1/24 | | | +| R3 | Fa0/0 | 192.168.11.254/24 | | +| Fa1/0 | 200.1.1.1/30 | | | +| tunnel | 1.1.1.2/24 | | | +| ISP router | Fa4/0 | 100.1.1.2/30 | | +| Fa5/0 | 200.1.1.2/30 | | | +| Fa0/0 | 201.1.1.254/24 | | | +| Server 0 | Fa0 | 10.10.11.1/24 | 10.10.11.254/24 | +| PC1 | Fa0 | 10.10.11.2/24 | 10.10.11.254/24 | +| PC5 | Fa0 | 10.10.11.3/24 | 10.10.11.254/24 | +| PC2 | Fa0 | 10.10.11.4/24 | 10.10.11.254/24 | +| Laptop0 | Fa0 | 201.1.1.1/24 | 201.1.1.254/24 | +| 公网DNS | Fa0 | 201.1.1.252/24 | 201.1.1.254/24 | +| 公网www | Fa0 | 201.1.1.253/24 | 201.1.1.254/24 | +| 公网PC | Fa0 | 201.1.1.2/24 | 201.1.1.254/24 | +| PC6 | Fa0 | 192.168.11.1/24 | 192.168.11.254/24 | + + + +(2)IP地址配置: + +按拓扑图地址规划要求: + +给各路由器配置对应的IP地址、子网掩码; + +给各PC机配置对应的IP地址、子网掩码、网关。 + +配置命令如下:(注意:配置命令要大概说明其含义) + +**R1 IP** **地址配置** + +``` +R1> enable #进入特权模式 +R1# configure terminal #进入全局模式 +R1(config)# interface fastEthernet 0/0 #进入fa0/0端口 +R1(config-if)# ip address 10.10.11.254 255.255.255.0 #配置IP和子网掩码 +R1(config-if)# no shutdown #启用端口 +R1(config-if)# exit #退出fa0/0端口 +R1(config)# interface fastEthernet 1/0 #进入fa1/0端口 +R1(config-if)# ip address 100.1.1.1 255.255.255.252 #配置IP和子网掩码 +R1(config-if)# no shutdown #启用端口 +R1(config-if)# exit #退出fa1/0端口 +``` + +**R3 IP** **地址配置** + +``` +R3> enable #进入特权模式 +R3# configure terminal #进入全局模式 +R3(config)# interface fastEthernet 0/0 #进入fa0/0端口 +R3(config-if)# ip address 192.168.11.254 255.255.255.0 #配置IP和子网掩码 +R3(config-if)# no shutdown #启用端口 +R3(config-if)# exit #退出fa0/0端口 +R3(config)# interface fastEthernet 1/0 #进入fa1/0端口 +R3(config-if)# ip address 200.1.1.1 255.255.255.252 #配置IP和子网掩码 +R3(config-if)# no shutdown #启用端口 +R3(config-if)# exit #退出fa1/0端口 +``` + +**ISP** **配置** + +``` +ISP> enable #进入特权模式 +ISP# configure terminal #进入全局模式 +ISP(config)# interface fastEthernet 4/0 #进入fa4/0端口 +ISP(config-if)# ip address 100.1.1.2 255.255.255.252 #配置IP和子网掩码 +ISP (config-if)# no shutdown #启用端口 +ISP(config-if)# exit #退出fa4/0端口 +ISP(config)# interface fastEthernet 5/0 #进入fa5/0端口 +ISP(config-if)# ip address 200.1.1.2 255.255.255.252 #配置IP和子网掩码 +ISP(config-if)# no shutdown #启用端口 +ISP(config-if)# exit #退出fa5/0端口 +ISP(config)# interface fastEthernet 0/0 #进入fa0/0端口 +ISP(config-if)# ip address 201.1.1.254 255.255.255.0 #配置IP和子网掩码 +ISP(config-if)# no shutdown #启用端口 +ISP(config-if)# exit #退出fa0/0端口 +``` + +3、在总公司和分公司边界路由器上配置默认路由,达到总公司和分公司公网地址互通,配置命令如下:(注意:配置命令要大概说明其含义) + +**R1** **配置默认路由** + +``` +R1(config)#ip route 0.0.0.0 0.0.0.0 100.1.1.2 #配置默认路由 +``` + +**R3** **配置默认路由** + +``` +R3(config)#ip route 0.0.0.0 0.0.0.0 100.1.1.2 #配置默认路由 +``` + +4、测试R1和R3的公网地址间的互通性(验证Internet互通),截图如下:(注意:说明为什么) + +![image008](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image008.png) + +> 答:可以互通,因为R1配置了默认路由,全部数据包转发给了ISP的Fa4/0端口,而R3配置了默认路由,全部数据包转发给了ISP的Fa5/0端口,最终数据包在同一个路由器的两个端口上,所以可以直接通信。 + + + +(二)路由器R1的SSH登录服务配置: + +1、SSH登录要求: + +在路由器R1上配置SSH登录服务,其中所有的域名、用户名、密码等皆为wtctx-YYY(YYY为姓名缩写) + +2、配置命令如下:(注意:配置命令要大概说明其含义) + +``` +R1(config)# hostname R1 #配置ssh前必须修改主机名 +R1(config)# ip domain-name wtctx-qh #给路由器设置域名 +R1(config)# crypto key generate rsa #生成rsa秘钥 +R1(config)# line vty 0 15 #进入vty端口,最多15人同时在线 +R1(config-line)# transport input ssh #启用SSH登录 +R1(config-line)# privilege level 15 #设置用户操作等级为最高级 +R1(config-line)# login local #使用本地验证 +R1(config-line)# exit #退出到全局模式 +R1(config)# username wtctx-qh password wtctx-qh #创建用户名和密码 +R1(config)# enable secret wtctx-qh #设置密文密码 +``` + +3、测试PC2 SSH登录R1,截图如下: + +![image012](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image012.jpg) + +(三)交换机端口安全配置: + +1、在总公司交换机上端口安全要求: + +(1)f0/1端口采用静态MAC地址学习方式,指定服务器0的MAC地址,端口最大MAC地址数为?违规处理方式shutdown + +(2)f0/2端口采用sticky MAC地址学习方式,端口最大MAC地址数为?违规处理方式restrict + +2、相关配置命令如下:(注意:配置命令要大概说明其含义) + +**Fa0/1** **端口配置** + +``` +Switch> en #进入特权模式 +Switch# configure terminal #进入全局模式 +Switch(config)# interface fastEthernet 0/1 #进入Fa0/1端口 +Switch(config-if)# shutdown #关闭端口,清空mac地址表 +Switch(config-if)# switchport mode access #端口定义为access口 +Switch(config-if)# switchport port-security #开启端口安全功能 +Switch(config-if)# switchport nonegotiate #禁用DTP +Switch(config-if)# switchport port-security maximum 1 #设置允许最大地址数为1 +Switch(config-if)# switchport port-security mac-address 0090.0C62.168A #绑定允许接入的地址 +Switch(config-if)# switchport port-security violation shutdown #指定违规处理行为 +Switch(config-if)# no shutdown #启用端口 +``` + +> 解析:端口最大mac地址数为1即可,由于Fa0/1与服务器0是直连的,绑定服务器0的mac地址即可限制其它设备接入。 + +**Fa0/2** **端口配置** + +``` +Switch> en #进入特权模式 +Switch# configure terminal #进入全局模式 +Switch(config)# interface fastEthernet 0/2 #进入Fa0/1端口 +Switch(config-if)# shutdown #关闭端口,清空mac地址表 +Switch(config-if)# switchport mode access #端口定义为access口 +Switch(config-if)# switchport port-security #开启端口安全功能 +Switch(config-if)# switchport nonegotiate #禁用DTP +Switch(config-if)# switchport port-security maximum 3 #设置允许最大地址数为3 +Switch(config-if)# switchport port-security mac-address sticky #绑定允许接入的地址 +Switch(config-if)# switchport port-security violation restrict #指定违规处理行为 +Switch(config-if)# no shutdown #启用端口 +``` + +> 解析:端口最大mac地址数为3,通过观察交换机的mac地址表可以看出,交换机一共粘贴到了三个地址,Fa0/2端口下另外一个交换机的Fa0/1号端口的mac地址,和PC1与PC5的mac地址。添加其他设备发现无法通信,表明最大数为3是正确的。 + +(四)无线局域网安全配置: + +在分公司无线路由器上做安全配置: + +1、基础安全设置:(XX为学号最后2位) + +1)修改无线路由器默认的管理密码为:wtctx + +![image015](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image015.png) + +2)修改LAN口地址:192.168.XX+1.1/24 + +![image017](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image017.png) + +3)修改SSID:wtctx18 + +![image019](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image019.png) + +4)无线安全配置: + + 认证:WPA2-PSK + + 加密:AES + + 预共享密钥:wtctx2020 + +![image021](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image021.png) + +2、进一步安全配置: + +1)隐藏SSID + +![image023](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image023.png) + +2)无线mac地址过滤 + + 只允许图中3台无线设备laptop0、Smartphone0、Table PC0的mac地址接入,其他不允许 + +| 设备 | mac地址 | +| ----------- | -------------- | +| Laptop0 | 0001.642A.4045 | +| Smartphone0 | 0001.4205.D0AC | +| Tablet PC0 | 0001.C7B0.ED9E | + +![image027](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image027.png) + +3、测试各无线终端与PC6的连通性,截图显示如下: + +![image029](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image029.png) + + + +(五)GRE over IPSec VPN配置: + +1、在企业总公司和分公司间配置GRE over IPSec VPN (企业总公司和分公司间参数一致),要求: + +(1)GRE tunnel两端地址分别为:1.1.1.1/24和1.1.1.2/24 ,tunnel编号为120 + +(2)企业总公司和分公司间运行rip协议或OSPF实现互通 + +(3)IPSec配置:设置IKE参数,策略优先级为1(预共享验证、DES加密、MD5验证,DH组2,预共享验证密钥为wtctx) + +(4)Ipsec SA 参数设置:ESP-DES加密、ESP-MD5-HMAC验证 + +(5)VPN数据流acl编号为110 + +(6)transform-set 命名为wtctxset1,crypto map命名为wtctxmap + +2、配置如下:(注意:配置命令要大概说明其含义) + +``` +R1(config)#interface tunnel 120 #创建虚拟tunnel端口 +R1(config-if)#ip address 1.1.1.1 255.255.255.0 #定义tunnel接口的IP地址 +R1(config-if)#tunnel source fastEthernet 1/0 #定义tunnel通道的源地址 +R1(config-if)#tunnel destination 200.1.1.1 #定义tunnel通道的目的地址 +R1(config)#router rip #启用rip路由协议 +R1(config-router)#version 2 #定义rip v2版本 +R1(config-router)#no auto-summary #关闭自动汇总 +R1(config-router)#network 10.10.11.0 #宣告自己的网段 +R1(config-router)#network 1.1.1.1 #宣告自己的网段 +R1(config-router)# exit #回到全局模式 +R1(config)# crypto isakmp enable #启用IKE +R1(config)# crypto isakmp policy 1 #建立IKE策略,优先级为1 +R1(config-isakmp)# authentication pre-share #使用预共享的密码进行身份验证 +R1(config-isakmp)# encryption des #使用DES加密方式 +R1(config-isakmp)# hash md5 #指定Hash算法为MD5 +R1(config-isakmp)# group 2 #指定秘钥位数,group2安全性更高 +R1(config-isakmp)# exit #回到全局模式 +R1(config)#access-list 110 permit gre host 100.1.1.1 host 200.1.1.1 #定义感兴趣流量 +R1(config)# crypto isakmp key wtctx address 200.1.1.1 #设置预共享秘钥和对端IP +R1(config)#crypto ipsec transform-set wtctxset1 esp-des esp-md5-hmac #配置IPSec交换集 +R1(config)#crypto map wtctxmap 1 ipsec-isakmp #创建加密图 +R1(config-crypto-map)#set peer 200.1.1.1 #标识对方路由器IP地址 +R1(config-crypto-map)#set transform-set wtctxset1 #指定加密图使用的IPSec交换集 +R1(config-crypto-map)#match address 110 #用ACL来定义加密的通信 +R1(config-crypto-map)#exit #回到全局模式 +R1(config)#interface fastEthernet 1/0 #进入Fa1/0端口 +R1(config-if)#crypto map wtctxmap #应用加密图到接口 +R3(config)#interface tunnel 120 #创建虚拟tunnel端口 +R3(config-if)#ip address 1.1.1.2 255.255.255.0 #定义tunnel接口的IP地址 +R3(config-if)#tunnel source fastEthernet 1/0 #定义tunnel通道的源地址 +R3(config-if)#tunnel destination 100.1.1.1 #定义tunnel通道的目的地址 +R3(config)#router rip #启用rip路由协议 +R3(config-router)#version 2 #定义rip v2版本 +R3(config-router)#no auto-summary #关闭自动汇总 +R3(config-router)#network 192.168.11.0 #宣告自己的网段 +R3(config-router)#network 1.1.1.2 #宣告自己的网段 +R3(config)# crypto isakmp enable #启用IKE +R3(config)# crypto isakmp policy 1 #建立IKE策略,优先级为1 +R3(config-isakmp)# authentication pre-share #使用预共享的密码进行身份验证 +R3(config-isakmp)# encryption des #使用DES加密方式 +R3(config-isakmp)# hash md5 #指定Hash算法为MD5 +R3(config-isakmp)# group 2 #指定秘钥位数,group2安全性更高 +R3(config-isakmp)# exit #回到全局模式 +R3(config)#access-list 110 permit gre host 200.1.1.1 host 100.1.1.1 #定义感兴趣流量 +R3(config)# crypto isakmp key wtctx address 100.1.1.1 #设置预共享秘钥和对端IP +R3(config)#crypto ipsec transform-set wtctxset1 esp-des esp-md5-hmac #配置IPSec交换集 +R3(config)#crypto map wtctxmap 1 ipsec-isakmp #创建加密图 +R3(config-crypto-map)#set peer 100.1.1.1 #标识对方路由器IP地址 +R3(config-crypto-map)#set transform-set wtctxset1 #指定加密图使用的IPSec交换集 +R3(config-crypto-map)#match address 110 #用ACL来定义加密的通信 +R3(config-crypto-map)#exit #回到全局模式 +R3(config)#interface fastEthernet 1/0 #进入Fa1/0端口 +R3(config-if)#crypto map wtctxmap #应用加密图到接口 +``` + +3、测试: + +总公司PC5和分公司PC6间以私有地址互访,截图如下: + +![image034](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image034.png) + +4、分析GRE over Ipsec VPN的数据包 + +![image038](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image038.png) + +![image036](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image036.png) + +![image040](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image040.png) + +> 答:可以看到入站前源地址和目的地址都是私网地址,经过路由器,从出站方向可以看到添加了GRE头部,然后添加了公网地址的头部,源地址和目的地址都为公网地址,然后经过IPsec加密,最后添加了公网地址的头部进行传送。 + + + +(六)Easy VPN配置: + +1、在R1上配置Easy VPN,配置策略要求如下: + +(1)设置IKE参数,策略优先级为2(预共享验证、DES加密、MD5验证、DH组2) + +(2)启动aaa,设置认证组名为wtc-a,授权组名为wtc-o,用户名和密码为wtc + +(3)设置策略组名为wtcgroup、密码为wtckey,地址池为wtcpool,地址范围172.16.1.1—172.16.1.254 + +(4)设置 transform-set 命名为wtctxset2(ESP-DES加密、ESP-MD5-HMAC验证),动态crypto map命名为wtcdmap,静态crypto map命名为wtctxmap + +2、配置命令如下:(注意:配置命令要大概说明其含义) + +``` +R1(config)# crypto isakmp policy 2 ##建立IKE策略,优先级为2 +R1(config-isakmp)# authentication pre-share #使用预共享的密码进行身份验证 +R1(config-isakmp)# encryption des #使用DES加密方式 +R1(config-isakmp)# hash md5 #指定Hash算法为MD5 +R1(config-isakmp)# group 2 #指定秘钥位数,group2安全性更高 +R1(config)# aaa new-model #启用aaa +R1(config)# aaa authentication login wtc-a local #认证 +R1(config)# aaa authorization network wtc-o local #授权 +R1(config)# username wtc password wtc #在交换机本地设置一个用户 +R1(config)# ip local pool wtcpool 172.16.1.1 172.16.1.254 #定义地址池 +R1(config)# crypto isakmp client configuration group wtcgroup #配置用户组策略 +R1(config-isakmp-group)# key wtckey #定义密码 +R1(config-isakmp-group)# pool wtcpool #定义使用的地址池 +R1(config-isakmp-group)# exit #回到全局模式 +R1(config)# crypto ipsec transform-set wtctxset2 esp-des esp-md5-hmac #配置IPSec交换集R1(config)# crypto dynamic-map wtcdmap 2 #定义动态保密图 +R1(config-crypto-map)# set transform-set wtctxset2 #设置调用的IPsec交换集 +R1(config-crypto-map)# reverse-route #路由器必须配置此功能 +R1(config-crypto-map)# exit #回到全局模式 +R1(config)# crypto map wtctxmap client authentication list wtc-a #设置认证用户列表 +R1(config)# crypto map wtctxmap isakmp authorization list wtc-o #设置授权用户列表 +R1(config)# crypto map wtctxmap client configuration address respond # VPN地址推送方式 +R1(config)# crypto map wtctxmap 2 ipsec-isakmp dynamic wtcdmap #将动态保密图映射到静态保密图 +R1(config-crypto-map)# exit #回到全局模式 +R1(config)# interface fastEthernet 1/0 #进入Fa1/0端口 +R1(config-if)# crypto map wtctxmap #关联到Fa1/0端口 +``` + + + +3、测试: + +出差员工PC以VPN登录,能访问公总司PC,截图显示 + +![image043](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image043.png) + +![image045](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image045.png) + +4、分析easy VPN的数据包 + +![image049](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image049.png) + +![image047](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image047.png) + +![image051](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image051.png) + +> 答:位于公网的电脑,登录easy VPN之后会自动获取到一个我们设置的地址池地址,和位于公司总部的电脑进行通信时,首先在公网这边的路由器ISP进站源地址是分配的地址池IP,目的地址为分公司私网地址,出站后添加了ESP头部,然后添加了公网地址头。在总公司路由器进站则是将添加了私网地址头,源地址为公网电脑登录VPN分配的地址池IP,目的地址为总公司内部的私网地址。 + + + +(七)NAT配置: + +1、在企业总公司边界路由器R1上配置静态一对多nat,实现公网PC能访问内网服务器0的web服务和ftp服务,要求: + +内网服务器对应的公网地址为:202.56.110.1 + +2、在企业总公司边界路由器R1上配置PAT,实现内网用户访问公网WWW服务器和公网PC,要求: + +(1)公网IP地址直接为私网接口地址; + +(2)私网地址acl编号为1 + +3、配置命令如下:(注意:配置命令要大概说明其含义) + +``` +R1(config)#interface fastEthernet 0/0 #进入Fa0/0端口 +R1(config-if)#ip nat inside #定义对于NAT来说内部接口 +R1(config)#interface fastEthernet 1/0 #进入Fa1/0端口 +R1(config-if)#ip nat outside #定义对于NAT来说外部接口 +R1(config)#ip nat inside source static tcp 10.10.11.1 80 202.56.110.1 80 +R1(config)#ip nat inside source static tcp 10.10.11.1 20 202.56.110.1 20 +R1(config)#ip nat inside source static tcp 10.10.11.1 21 202.56.110.1 21 +``` + +``` +ISP(config)#ip route 202.56.110.1 255.255.255.255 100.1.1.1 #配置静态路由 +``` + +``` +R1(config)#access-list 1 permit 10.10.11.0 0.0.0.255 #acl列表 +R1(config)#ip nat inside source list 1 interface fastEthernet 1/0 overload #定义转换源 +``` + +4、测试: + +(1)公网PC能访问总公司内网服务器0的www服务,截图如下: + +![image056](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image056.png) + +(2)公网PC能访问总公司内网服务器0的ftp服务,截图如下: + +![image058](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image058.png) + +(3)总公司PC能访问公网服务器,截图如下: + +![image060](https://cdn.jsdelivr.net/gh/queen999/ImageHosting/images/image060.png) \ No newline at end of file diff --git a/source/_posts/not-allow-F12.md b/source/_posts/not-allow-F12.md index 6842c0b..c8cac2d 100644 --- a/source/_posts/not-allow-F12.md +++ b/source/_posts/not-allow-F12.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 小技巧 date: 2020-05-19 22:25:11 -music: - type: song - id: 1387581250 comments: true --- diff --git a/source/_posts/optical_transport_network_basic.md b/source/_posts/optical_transport_network_basic.md index 79c1a72..5e04a4f 100644 --- a/source/_posts/optical_transport_network_basic.md +++ b/source/_posts/optical_transport_network_basic.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-03-07 16:30:00 -music: - type: song - id: 1331819951 comments: true tags: - 通信技术 diff --git a/source/_posts/python-2.md b/source/_posts/python-2.md index aeaf005..855f255 100644 --- a/source/_posts/python-2.md +++ b/source/_posts/python-2.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Python date: 2020-05-20 20:13:14 -music: - type: song - id: 440353010 comments: true --- diff --git a/source/_posts/ssh.md b/source/_posts/ssh.md index 57b04e4..98da106 100644 --- a/source/_posts/ssh.md +++ b/source/_posts/ssh.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 网络安全 date: 2020-02-24 17:52:30 -music: - type: song - id: 1376142151 comments: true tags: - 网络安全 diff --git a/source/_posts/structure-of-MAN.md b/source/_posts/structure-of-MAN.md index 4e680fb..a118134 100644 --- a/source/_posts/structure-of-MAN.md +++ b/source/_posts/structure-of-MAN.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 计算机三级 date: 2020-04-13 09:46:11 -music: - type: song - id: 550138197 comments: true tags: - 网络技术 diff --git a/source/_posts/switchport-security.md b/source/_posts/switchport-security.md index 339995b..7b979bd 100644 --- a/source/_posts/switchport-security.md +++ b/source/_posts/switchport-security.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 网络安全 date: 2020-02-27 11:11:11 -music: - type: song - id: 1404885266 comments: true tags: - 网络安全 diff --git a/source/_posts/system_info.md b/source/_posts/system_info.md index b792d35..7af2fd4 100644 --- a/source/_posts/system_info.md +++ b/source/_posts/system_info.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: Linux date: 2020-08-13 20:14:14 -music: - type: song - id: 1363205817 comments: true --- diff --git a/source/_posts/wireless_framework.md b/source/_posts/wireless_framework.md index 407e90e..c2e4e6a 100644 --- a/source/_posts/wireless_framework.md +++ b/source/_posts/wireless_framework.md @@ -6,11 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-04-09 11:25:00 -music: - enable: true - server: netease - type: song - id: 1374329431 comments: true tags: - 通信技术 diff --git a/source/_posts/wireless_radio.md b/source/_posts/wireless_radio.md index e0b59fb..dd39159 100644 --- a/source/_posts/wireless_radio.md +++ b/source/_posts/wireless_radio.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-03-07 13:00:00 -music: - type: song - id: 477754663 comments: true tags: - 通信技术 diff --git a/source/_posts/wireless_word.md b/source/_posts/wireless_word.md index 2cdd406..f3a6be3 100644 --- a/source/_posts/wireless_word.md +++ b/source/_posts/wireless_word.md @@ -6,9 +6,6 @@ author: url: https://www.zhengyuanyuan520.com categories: 通信技术 date: 2020-03-06 15:00:00 -music: - type: song - id: 1302090321 comments: true tags: - 通信技术 diff --git a/source/friends/index.md b/source/friends/index.md index abf427c..1976134 100644 --- a/source/friends/index.md +++ b/source/friends/index.md @@ -13,7 +13,7 @@ links: url: https://xaoxuu.com tags: [ios] - name: TRHX’S BLOG - avatar: https://www.itrhx.com/images/trhx.png + avatar: https://cdn.jsdelivr.net/gh/TRHX/CDN-for-itrhx.com@3.1.1/images/trhx.png url: https://www.itrhx.com/ tags: [Python, 爬虫, 前端] - name: hojun @@ -24,4 +24,8 @@ links: avatar: https://jerryc.me/img/avatar.png url: https://jerryc.me/ tags: [今日事,今日毕] + - name: kelevc + avatar: https://skyqin1999.oss-cn-beijing.aliyuncs.com/Blog/site/233.jpg + url: http://www.kelevc.cn/ + tags: [没有绝对真理] --- \ No newline at end of file diff --git a/source/hexo-offline-popup/.babelrc b/source/hexo-offline-popup/.babelrc deleted file mode 100644 index 430184f..0000000 --- a/source/hexo-offline-popup/.babelrc +++ /dev/null @@ -1,33 +0,0 @@ -{ - "env": { - "test": { - "plugins": [ - "istanbul" - ], - "presets": [ - [ - "env", - { - "targets": { - "node": 4 - } - } - ] - ] - } - }, - "ignore": [ - "./src/templates/inject.tpl.js", - "./src/templates/sw-register.tpl.js" - ], - "presets": [ - [ - "env", - { - "targets": { - "node": 4 - } - } - ] - ] -} diff --git a/source/hexo-offline-popup/.editorconfig b/source/hexo-offline-popup/.editorconfig deleted file mode 100644 index 5157391..0000000 --- a/source/hexo-offline-popup/.editorconfig +++ /dev/null @@ -1,17 +0,0 @@ -# This file is for unifying the coding style for different editors and IDEs -# editorconfig.org - -root = true - -[*] -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.{js,styl,html,json}] -indent_size = 4 -indent_style = space - -[*.md] -trim_trailing_whitespace = false diff --git a/source/hexo-offline-popup/.fecsignore b/source/hexo-offline-popup/.fecsignore deleted file mode 100644 index 68f0291..0000000 --- a/source/hexo-offline-popup/.fecsignore +++ /dev/null @@ -1,12 +0,0 @@ -.DS_Store -._.DS_Store -dist -tmp -*.log -*.tmp -node_modules -lib -src/lib/*.tpl.js -coverage -.nyc_output -npm-debug.* diff --git a/source/hexo-offline-popup/.fecsrc b/source/hexo-offline-popup/.fecsrc deleted file mode 100644 index d71445a..0000000 --- a/source/hexo-offline-popup/.fecsrc +++ /dev/null @@ -1,20 +0,0 @@ -{ - "eslint": { - "env": { - "node": true, - "browser": true - }, - - "globals": { - "console": true, - "require": true, - "define": true - }, - - "rules": { - "no-console": 0, - "brace-style": [2, "1tabs"], - "fecs-no-require": "off" - } - } -} diff --git a/source/hexo-offline-popup/.nycrc b/source/hexo-offline-popup/.nycrc deleted file mode 100644 index d8d9c14..0000000 --- a/source/hexo-offline-popup/.nycrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "require": [ - "babel-register" - ], - "sourceMap": false, - "instrument": false -} diff --git a/source/hexo-offline-popup/.travis.yml b/source/hexo-offline-popup/.travis.yml deleted file mode 100644 index 71b3da1..0000000 --- a/source/hexo-offline-popup/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: node_js -node_js: - - "4" - - "6" - - "8" - -cache: yarn -matrix: - fast_finish: true - -after_success: - - yarn add coveralls - - yarn run coverage -- --reporter=text-lcov | ./node_modules/.bin/coveralls - -before_install: yarn global add greenkeeper-lockfile@1 -before_script: greenkeeper-lockfile-update -after_script: greenkeeper-lockfile-upload diff --git a/source/hexo-offline-popup/CHANGELOG.md b/source/hexo-offline-popup/CHANGELOG.md deleted file mode 100644 index e69de29..0000000 diff --git a/source/hexo-offline-popup/LICENSE b/source/hexo-offline-popup/LICENSE deleted file mode 100644 index e69de29..0000000 diff --git a/source/hexo-offline-popup/README.md b/source/hexo-offline-popup/README.md deleted file mode 100644 index 8a5187a..0000000 --- a/source/hexo-offline-popup/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# hexo-offline-popup - -hexo-offline-popup 是一个 [hexo](https://hexo.io) 插件, 它可加速您的Hexo网站的加载速度,以及网站内容更新弹窗提示。 - -该插件基于停止维护已久的hexo-service-worker插件,并在它的基础上加以改进。 - -## Install - -```bash -npm i hexo-offline-popup --save -``` - -安装后, 运行 `hexo clean && hexo generate` 激活插件. - -## Usage - -如果网站提供的所有内容来自原始服务器,你不需要添加任何配置。只需安装和运行 `hexo clean && hexo generate`。 - -在博客根目录的 `_config.yml` 中添加以下配置. - -```yaml -# offline config passed to sw-precache. -service_worker: - maximumFileSizeToCacheInBytes: 5242880 - staticFileGlobs: - - public/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff,woff2} - stripPrefix: public - verbose: true -``` - -如果你有CDN资源,例: - -```yaml -- https://cdn.some.com/some/path/some-script.js -- http://cdn.some-else.org/some/path/deeply/some-style.css -``` - -将此配置添加到根目录的 `_config.yml` - -```yaml -service_worker: - runtimeCaching: - - urlPattern: /* - handler: cacheFirst - options: - origin: cdn.some.com - - urlPattern: /* - handler: cacheFirst - options: - origin: cdn.some-else.org -``` diff --git a/source/hexo-offline-popup/appveyor.yml b/source/hexo-offline-popup/appveyor.yml deleted file mode 100644 index 777a41f..0000000 --- a/source/hexo-offline-popup/appveyor.yml +++ /dev/null @@ -1,34 +0,0 @@ -# Fix line endings in Windows. (runs before repo cloning) -init: - - git config --global core.autocrlf input - -# Test against these versions of Node.js. -environment: - matrix: - - nodejs_version: "4" - - nodejs_version: "6" - - nodejs_version: "8" - -matrix: - fast_finish: true - -# Install scripts. (runs after repo cloning) -install: - - ps: Install-Product node $env:nodejs_version - - npm install - -cache: - - node_modules - -# Post-install test scripts. -test_script: - - npm test - -# Don't actually build. -build: off - -# Don't actually deploy. -deploy: off - -# Set build version format here instead of in the admin panel. -version: "{build}" diff --git a/source/hexo-offline-popup/build.sh b/source/hexo-offline-popup/build.sh deleted file mode 100644 index e69de29..0000000 diff --git a/source/hexo-offline-popup/lib/config.js b/source/hexo-offline-popup/lib/config.js deleted file mode 100644 index c58fdab..0000000 --- a/source/hexo-offline-popup/lib/config.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * @file config for plugin - * @author mj(zoumiaojiang@gmail.com) - */ - -var SW_FILE_NAME = exports.SW_FILE_NAME = 'sw.js'; \ No newline at end of file diff --git a/source/hexo-offline-popup/lib/index.js b/source/hexo-offline-popup/lib/index.js deleted file mode 100644 index cf27b89..0000000 --- a/source/hexo-offline-popup/lib/index.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -var _runSwPrecache = require('./run-sw-precache'); - -var _runSwPrecache2 = _interopRequireDefault(_runSwPrecache); - -var _runSwRegister = require('./run-sw-register'); - -var _runSwRegister2 = _interopRequireDefault(_runSwRegister); - -var _inject = require('./inject'); - -var _inject2 = _interopRequireDefault(_inject); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function serviceWorkerHandler() { - var _this = this; - - return Promise.all([_runSwPrecache2.default.call(this), _runSwRegister2.default.call(this)]).then(function () { - return (0, _inject2.default)(_this.public_dir); - }); -} /** - * @file hexo plugin entry - * @author mj(zoumiaojiang@gmail.com) - */ - -/* global hexo */ - - -hexo.extend.filter.register('before_exit', serviceWorkerHandler); \ No newline at end of file diff --git a/source/hexo-offline-popup/lib/inject.js b/source/hexo-offline-popup/lib/inject.js deleted file mode 100644 index f3b2fcb..0000000 --- a/source/hexo-offline-popup/lib/inject.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = inject; - -var _fs = require('fs'); - -var _fs2 = _interopRequireDefault(_fs); - -var _path = require('path'); - -var _path2 = _interopRequireDefault(_path); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * @file inject service worker to hexo page - * @author mj(zoumiaojiang@gmail.com) - */ - -var injectScriptCon = _fs2.default.readFileSync(_path2.default.join(__dirname, 'templates', 'inject.tpl.js'), 'utf-8'); -var injectScript = ``; - -function inject(publicDir) { - - _fs2.default.readdirSync(publicDir).forEach(function (item) { - var itemPath = _path2.default.resolve(publicDir, item); - - if (_fs2.default.statSync(itemPath).isFile()) { - if (/\.html$/.test(item)) { - var indexHTMLPath = _path2.default.join(publicDir, item); - var fileContent = _fs2.default.readFileSync(indexHTMLPath, 'utf-8').toString(); - - // if it has not been injected before - if (!fileContent.includes(`${injectScript}`)) { - var injectedContent = fileContent.replace(/<\/body>\s*<\/html>\s*$/, `${injectScript}`); - _fs2.default.writeFileSync(indexHTMLPath, injectedContent); - } - } - } else if (_fs2.default.statSync(itemPath).isDirectory()) { - inject(itemPath); - } - }); -} \ No newline at end of file diff --git a/source/hexo-offline-popup/lib/run-sw-precache.js b/source/hexo-offline-popup/lib/run-sw-precache.js deleted file mode 100644 index 6c5d893..0000000 --- a/source/hexo-offline-popup/lib/run-sw-precache.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -exports.default = function () { - var public_dir = this.public_dir, - config = this.config, - log = this.log; - var root = config.root, - service_worker = config.service_worker; - - - var hexoPublicDir = 'public'; - var rootPrefix = root.replace(/\/$/, ''); - var SWPrecacheConfig = Object.assign({ - logger: log.info.bind(log), - replacePrefix: rootPrefix, - staticFileGlobs: [hexoPublicDir + '/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff}'], - stripPrefix: hexoPublicDir, - templateFilePath: _path2.default.resolve(__dirname, 'templates', 'sw-precache.tpl') - }, service_worker); - - return _swPrecache2.default.write(_path2.default.join(public_dir, _config.SW_FILE_NAME), SWPrecacheConfig); -}; - -var _path = require('path'); - -var _path2 = _interopRequireDefault(_path); - -var _swPrecache = require('sw-precache'); - -var _swPrecache2 = _interopRequireDefault(_swPrecache); - -var _config = require('./config'); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } \ No newline at end of file diff --git a/source/hexo-offline-popup/lib/run-sw-register.js b/source/hexo-offline-popup/lib/run-sw-register.js deleted file mode 100644 index 6c8df1a..0000000 --- a/source/hexo-offline-popup/lib/run-sw-register.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -exports.default = function () { - var swRegisterTemplatePath = _path2.default.resolve(__dirname, 'templates', 'sw-register.tpl.js'); - var swRegisterTempleteCon = _fs2.default.readFileSync(swRegisterTemplatePath, 'utf-8'); - var swRegisterCon = swRegisterTempleteCon.replace('__ServiceWorkerName__', _config.SW_FILE_NAME).replace('__BuildVersion__', versionGenerator()); - - var swRegisterDistPath = _path2.default.resolve(this.public_dir, 'sw-register.js'); - - _fs2.default.writeFileSync(swRegisterDistPath, swRegisterCon); - - return Promise.resolve(); -}; - -var _fs = require('fs'); - -var _fs2 = _interopRequireDefault(_fs); - -var _path = require('path'); - -var _path2 = _interopRequireDefault(_path); - -var _config = require('./config'); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * 对于小于 10 的数字向左补全0 - * - * @param {number} value 数字 - * @return {string} 补全后的字符串 - */ -function padding(value) { - return value < 10 ? `0${value}` : value; -} - -/** - * 获取时间戳版本号 - * - * @return {string} 版本号 - */ -/** - * @file run sw-precache - * @author mj(zoumiaojiang@gmail.com) - */ - -/* global public_dir */ -/* eslint-disable fecs-camelcase */ -function versionGenerator() { - var d = new Date(); - - return '' + d.getFullYear() + padding(d.getMonth() + 1) + padding(d.getDate()) + padding(d.getHours()) + padding(d.getMinutes()) + padding(d.getSeconds()); -} \ No newline at end of file diff --git a/source/hexo-offline-popup/lib/templates/inject.tpl.js b/source/hexo-offline-popup/lib/templates/inject.tpl.js deleted file mode 100644 index b1b6df0..0000000 --- a/source/hexo-offline-popup/lib/templates/inject.tpl.js +++ /dev/null @@ -1 +0,0 @@ -window.onload=function(){var a=document.createElement('script'),b=document.getElementsByTagName('script')[0];a.type='text/javascript',a.async=!0,a.src='/sw-register.js?v='+Date.now(),b.parentNode.insertBefore(a,b)}; \ No newline at end of file diff --git a/source/hexo-offline-popup/lib/templates/sw-precache.tpl b/source/hexo-offline-popup/lib/templates/sw-precache.tpl deleted file mode 100644 index a9a152f..0000000 --- a/source/hexo-offline-popup/lib/templates/sw-precache.tpl +++ /dev/null @@ -1,280 +0,0 @@ -/** - * 自动引入模板,在原有 sw-precache 插件默认模板基础上做的二次开发 - * - * 因为是自定导入的模板,项目一旦生成,不支持随 sw-precache 的版本自动升级。 - * 可以到 Lavas 官网下载 basic 模板内获取最新模板进行替换 - * - */ - -/* eslint-disable */ - -'use strict'; - -var precacheConfig = <%= precacheConfig %>; -var cacheName = 'sw-precache-<%= version %>-<%= cacheId %>-' + (self.registration ? self.registration.scope : ''); -var firstRegister = 1; // 默认1是首次安装SW, 0是SW更新 - -<% if (handleFetch) { %> -var ignoreUrlParametersMatching = [<%= ignoreUrlParametersMatching %>]; -<% } %> - -var addDirectoryIndex = function (originalUrl, index) { - var url = new URL(originalUrl); - if (url.pathname.slice(-1) === '/') { - url.pathname += index; - } - return url.toString(); -}; - -var cleanResponse = function (originalResponse) { - // 如果没有重定向响应,不需干啥 - if (!originalResponse.redirected) { - return Promise.resolve(originalResponse); - } - - // Firefox 50 及以下不知处 Response.body 流, 所以我们需要读取整个body以blob形式返回。 - var bodyPromise = 'body' in originalResponse ? - Promise.resolve(originalResponse.body) : - originalResponse.blob(); - - return bodyPromise.then(function (body) { - // new Response() 可同时支持 stream or Blob. - return new Response(body, { - headers: originalResponse.headers, - status: originalResponse.status, - statusText: originalResponse.statusText - }); - }); -}; - -var createCacheKey = function (originalUrl, paramName, paramValue, - dontCacheBustUrlsMatching) { - - // 创建一个新的URL对象,避免影响原始URL - var url = new URL(originalUrl); - - // 如果 dontCacheBustUrlsMatching 值没有设置,或是没有匹配到,将值拼接到url.serach后 - if (!dontCacheBustUrlsMatching || - !(url.pathname.match(dontCacheBustUrlsMatching))) { - url.search += (url.search ? '&' : '') + - encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue); - } - - return url.toString(); -}; - -var isPathWhitelisted = function (whitelist, absoluteUrlString) { - // 如果 whitelist 是空数组,则认为全部都在白名单内 - if (whitelist.length === 0) { - return true; - } - - // 否则逐个匹配正则匹配并返回 - var path = (new URL(absoluteUrlString)).pathname; - return whitelist.some(function (whitelistedPathRegex) { - return path.match(whitelistedPathRegex); - }); -}; - -var stripIgnoredUrlParameters = function (originalUrl, - ignoreUrlParametersMatching) { - var url = new URL(originalUrl); - // 移除 hash; 查看 https://github.com/GoogleChrome/sw-precache/issues/290 - url.hash = ''; - - url.search = url.search.slice(1) // 是否包含 '?' - .split('&') // 分割成数组 'key=value' 的形式 - .map(function (kv) { - return kv.split('='); // 分割每个 'key=value' 字符串成 [key, value] 形式 - }) - .filter(function (kv) { - return ignoreUrlParametersMatching.every(function (ignoredRegex) { - return !ignoredRegex.test(kv[0]); // 如果 key 没有匹配到任何忽略参数正则,就 Return true - }); - }) - .map(function (kv) { - return kv.join('='); // 重新把 [key, value] 格式转换为 'key=value' 字符串 - }) - .join('&'); // 将所有参数 'key=value' 以 '&' 拼接 - - return url.toString(); -}; - - -var addDirectoryIndex = function (originalUrl, index) { - var url = new URL(originalUrl); - if (url.pathname.slice(-1) === '/') { - url.pathname += index; - } - return url.toString(); -}; - -var hashParamName = '_sw-precache'; -var urlsToCacheKeys = new Map( - precacheConfig.map(function (item) { - var relativeUrl = item[0]; - var hash = item[1]; - var absoluteUrl = new URL(relativeUrl, self.location); - var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, <%= dontCacheBustUrlsMatching %>); - return [absoluteUrl.toString(), cacheKey]; - }) -); - -function setOfCachedUrls(cache) { - return cache.keys().then(function (requests) { - // 如果原cacheName中没有缓存任何收,就默认是首次安装,否则认为是SW更新 - if (requests && requests.length > 0) { - firstRegister = 0; // SW更新 - } - return requests.map(function (request) { - return request.url; - }); - }).then(function (urls) { - return new Set(urls); - }); -} - -self.addEventListener('install', function (event) { - event.waitUntil( - caches.open(cacheName).then(function (cache) { - return setOfCachedUrls(cache).then(function (cachedUrls) { - return Promise.all( - Array.from(urlsToCacheKeys.values()).map(function (cacheKey) { - // 如果缓存中没有匹配到cacheKey,添加进去 - if (!cachedUrls.has(cacheKey)) { - var request = new Request(cacheKey, { credentials: 'same-origin' }); - return fetch(request).then(function (response) { - // 只要返回200才能继续,否则直接抛错 - if (!response.ok) { - throw new Error('Request for ' + cacheKey + ' returned a ' + - 'response with status ' + response.status); - } - - return cleanResponse(response).then(function (responseToCache) { - return cache.put(cacheKey, responseToCache); - }); - }); - } - }) - ); - }); - }) - .then(function () { - <% if (skipWaiting) { %> - // 强制 SW 状态 installing -> activate - return self.skipWaiting(); - <% } %> - }) - ); -}); - -self.addEventListener('activate', function (event) { - var setOfExpectedUrls = new Set(urlsToCacheKeys.values()); - - event.waitUntil( - caches.open(cacheName).then(function (cache) { - return cache.keys().then(function (existingRequests) { - return Promise.all( - existingRequests.map(function (existingRequest) { - // 删除原缓存中相同键值内容 - if (!setOfExpectedUrls.has(existingRequest.url)) { - return cache.delete(existingRequest); - } - }) - ); - }); - }).then(function () { - <% if (clientsClaim) { %> - return self.clients.claim(); - <% } %> - }).then(function () { - // 如果是首次安装 SW 时, 不发送更新消息(是否是首次安装,通过指定cacheName 中是否有缓存信息判断) - // 如果不是首次安装,则是内容有更新,需要通知页面重载更新 - if (!firstRegister) { - return self.clients.matchAll() - .then(function (clients) { - if (clients && clients.length) { - clients.forEach(function (client) { - client.postMessage('sw.update'); - }) - } - }) - } - }) - ); -}); - - -<% if (handleFetch) { %> - self.addEventListener('fetch', function (event) { - if (event.request.method === 'GET') { - - // 是否应该 event.respondWith(),需要我们逐步的判断 - // 而且也方便了后期做特殊的特殊 - var shouldRespond; - - - // 首先去除已配置的忽略参数及hash - // 查看缓存简直中是否包含该请求,包含就将shouldRespond 设为true - var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching); - shouldRespond = urlsToCacheKeys.has(url); - - // 如果 shouldRespond 是 false, 我们在url后默认增加 'index.html' - // (或者是你在配置文件中自行配置的 directoryIndex 参数值),继续查找缓存列表 - var directoryIndex = '<%= directoryIndex %>'; - if (!shouldRespond && directoryIndex) { - url = addDirectoryIndex(url, directoryIndex); - shouldRespond = urlsToCacheKeys.has(url); - } - - // 如果 shouldRespond 仍是 false,检查是否是navigation - // request, 如果是的话,判断是否能与 navigateFallbackWhitelist 正则列表匹配 - var navigateFallback = '<%= navigateFallback %>'; - if (!shouldRespond && - navigateFallback && - (event.request.mode === 'navigate') && - isPathWhitelisted(<%= navigateFallbackWhitelist %>, event.request.url) - ) { - url = new URL(navigateFallback, self.location).toString(); - shouldRespond = urlsToCacheKeys.has(url); - } - - // 如果 shouldRespond 被置为 true - // 则 event.respondWith()匹配缓存返回结果,匹配不成就直接请求. - if (shouldRespond) { - event.respondWith( - caches.open(cacheName).then(function (cache) { - return cache.match(urlsToCacheKeys.get(url)).then(function (response) { - if (response) { - return response; - } - throw Error('The cached response that was expected is missing.'); - }); - }).catch(function (e) { - // 如果捕获到异常错误,直接返回 fetch() 请求资源 - console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e); - return fetch(event.request); - }) - ); - } - } - }); - - -<% if (swToolboxCode) { %> -// *** Start of auto-included sw-toolbox code. *** -<%= swToolboxCode %> -// *** End of auto-included sw-toolbox code. *** -<% } %> - -<% if (runtimeCaching) { %> -// Runtime cache 配置转换后的 toolbox 代码. -<%= runtimeCaching %> -<% } %> -<% } %> - -<% if (importScripts) { %> - importScripts(<%= importScripts %>); -<% } %> - -/* eslint-enable */ diff --git a/source/hexo-offline-popup/lib/templates/sw-register.tpl.js b/source/hexo-offline-popup/lib/templates/sw-register.tpl.js deleted file mode 100644 index 03802ac..0000000 --- a/source/hexo-offline-popup/lib/templates/sw-register.tpl.js +++ /dev/null @@ -1 +0,0 @@ -navigator.serviceWorker&&navigator.serviceWorker.register('/__ServiceWorkerName__?v=__BuildVersion__').then(function(){navigator.serviceWorker.addEventListener('message',function(a){if('sw.update'===a.data){let a=document.querySelector('meta[name=theme-color]'),b=document.createElement('div');a&&(a.content='#000'),b.innerHTML='

\u64cd\u4f5c\u901a\u77e5

\u5df2\u66f4\u65b0\u6700\u65b0\u7248\u672c\uff08\u5237\u65b0\u751f\u6548\uff09
×
',document.body.appendChild(b),setTimeout(function(){document.getElementById('app-refresh').className+=' app-refresh-show'},16)}})}); \ No newline at end of file diff --git a/source/hexo-offline-popup/package.json b/source/hexo-offline-popup/package.json deleted file mode 100644 index 2919f9e..0000000 --- a/source/hexo-offline-popup/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "_from": "hexo-offline-popup", - "_id": "hexo-offline-popup@1.0.3", - "_inBundle": false, - "_integrity": "sha512-Lhv0vAXffJVwqMObyK+EjW4lfsjmzj+sVnCJc/pssmj9W+O+Mal57bgLV5dLuAV82u/57TQ4BtvdpLOTtkH99Q==", - "_location": "/hexo-offline-popup", - "_phantomChildren": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.4", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - }, - "_requested": { - "type": "tag", - "registry": true, - "raw": "hexo-offline-popup", - "name": "hexo-offline-popup", - "escapedName": "hexo-offline-popup", - "rawSpec": "", - "saveSpec": null, - "fetchSpec": "latest" - }, - "_requiredBy": [ - "#USER", - "/" - ], - "_resolved": "https://registry.npmjs.org/hexo-offline-popup/-/hexo-offline-popup-1.0.3.tgz", - "_shasum": "4a1d7e3e7280001c710315dcc65db753233ed81f", - "_spec": "hexo-offline-popup", - "_where": "D:\\qinhao\\hexo", - "author": { - "name": "colsrch" - }, - "bugs": { - "url": "https://github.com/Colsrch/hexo-offline-popup/issues" - }, - "bundleDependencies": false, - "dependencies": { - "babel-cli": "^6.26.0", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-babili": "^0.1.4", - "babel-preset-env": "^1.7.0", - "babel-register": "^6.26.0", - "cross-env": "^7.0.2", - "fecs": "^1.6.4", - "fs-extra": "^9.0.1", - "nyc": "^15.1.0", - "pre-commit": "^1.2.2", - "rimraf": "^3.0.2", - "sw-precache": "^5.2.1", - "tap": "^14.10.7" - }, - "deprecated": false, - "description": "实现加速Hexo网站的加载速度、网站内容更新弹窗提示", - "devDependencies": {}, - "directories": { - "lib": "lib", - "test": "test" - }, - "homepage": "https://github.com/Colsrch/hexo-offline-popup#readme", - "keywords": [ - "hexo-offline-popup" - ], - "license": "ISC", - "main": "lib/index.js", - "name": "hexo-offline-popup", - "repository": { - "type": "git", - "url": "git+https://github.com/Colsrch/hexo-offline-popup.git" - }, - "scripts": { - "test": "tap test/*.js" - }, - "version": "1.0.3" -} diff --git a/source/hexo-offline-popup/test/specs/inject.test.js b/source/hexo-offline-popup/test/specs/inject.test.js deleted file mode 100644 index 6717199..0000000 --- a/source/hexo-offline-popup/test/specs/inject.test.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file inject to html file's test - * @author mj(zoumiaoijiang@gmail.com) - */ - -import tap from 'tap'; -import fs from 'fs-extra'; -import path from 'path'; -import injectSWRegisterEntry from '../../src/inject'; - - -let test = tap.test; - -test('inject should inject script when index.html presents', t => { - let publicDir = path.resolve('./inject.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirSync(publicDir); - - let html = [ - '', - '', - ' ', - '' - ].join('\n'); - - let indexHTMLPath = path.join(publicDir, 'index.html'); - fs.writeFileSync(indexHTMLPath, html); - - injectSWRegisterEntry(publicDir); - let content = fs.readFileSync(indexHTMLPath, 'utf-8'); - t.ok(content.includes('')); - t.ok(content.includes('sw-register.js')); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); -}); - -test('inject should success when html file in sub dir', t => { - let publicDir = path.resolve('./inject.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirpSync(path.resolve(publicDir, 'subdir')); - let html = [ - '', - '', - ' ', - '' - ].join('\n'); - - let indexfirstLevelHTMLPath = path.join('./inject.test', 'index.html'); - let index2LevelHTMLPath = path.join('./inject.test/subdir', 'index.html'); - - fs.writeFileSync(indexfirstLevelHTMLPath, html); - fs.writeFileSync(index2LevelHTMLPath, html); - - injectSWRegisterEntry(publicDir); - let content = fs.readFileSync(indexfirstLevelHTMLPath, 'utf-8'); - let content2 = fs.readFileSync(index2LevelHTMLPath, 'utf-8'); - t.ok(content.includes('')); - t.ok(content2.includes('')); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); -}); - -test('inject should not throw when index.html is not found', t => { - let publicDir = path.resolve('./inject.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirSync(publicDir); - - t.doesNotThrow(() => injectSWRegisterEntry(publicDir)); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); -}); - -test('inject-sw-register should not inject script agian once injected', t => { - let publicDir = path.resolve('./inject.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirSync(publicDir); - - let html = [ - '', - '', - ' ', - '' - ].join('\n'); - - let indexHTMLPath = path.join(publicDir, 'index.html'); - fs.writeFileSync(indexHTMLPath, html); - - injectSWRegisterEntry(publicDir); - let content = fs.readFileSync(indexHTMLPath, 'utf-8'); - - injectSWRegisterEntry(publicDir); - let newContent = fs.readFileSync(indexHTMLPath, 'utf-8'); - - t.equal(content, newContent); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); -}); diff --git a/source/hexo-offline-popup/test/specs/run-sw-precache.test.js b/source/hexo-offline-popup/test/specs/run-sw-precache.test.js deleted file mode 100644 index dbdd4e3..0000000 --- a/source/hexo-offline-popup/test/specs/run-sw-precache.test.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file test of sw-precache - * @author mj(zoumiaojiang@gmail.com) - */ - -import {test} from 'tap'; -import fs from 'fs-extra'; -import path from 'path'; -import runSWPrecache from '../../src/run-sw-precache'; -import {SW_FILE_NAME} from '../../src/config'; - -/* eslint-disable fecs-camelcase */ -test('run-sw-precache should generate sw.js when index.html presents', t => { - let publicDir = path.resolve('./run-sw-precache.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirpSync(publicDir); - - let context = { - public_dir: publicDir, - config: { - root: '/', - service_worker: {} - }, - log: console - }; - - let cleanup = () => { - fs.existsSync(publicDir) && fs.removeSync(publicDir); - }; - - return runSWPrecache.call(context).then(() => { - let workerPath = path.join(publicDir, SW_FILE_NAME); - t.ok(fs.existsSync(workerPath)); - cleanup(); - t.end(); - }, error => { - console.error(error); - cleanup(); - t.end(); - }); -}); - -test('run-sw-precache should generate sw.js when use custom sw.tmpl', t => { - let publicDir = path.resolve('./run-sw-precache.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirSync(publicDir); - - let context = { - public_dir: publicDir, - config: { - root: '/', - service_worker: {} - }, - log: console - }; - - let cleanup = () => { - fs.existsSync(publicDir) && fs.removeSync(publicDir); - }; - - return runSWPrecache.call(context).then(() => { - let workerPath = path.join(publicDir, SW_FILE_NAME); - let swCon = fs.readFileSync(workerPath, 'utf-8'); - t.ok(swCon.includes('sw.update')); - cleanup(); - t.end(); - }, error => { - console.error(error); - cleanup(); - t.end(); - }); -}); diff --git a/source/hexo-offline-popup/test/specs/run-sw-register.test.js b/source/hexo-offline-popup/test/specs/run-sw-register.test.js deleted file mode 100644 index d960e1a..0000000 --- a/source/hexo-offline-popup/test/specs/run-sw-register.test.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file inject to html file's test - * @author mj(zoumiaoijiang@gmail.com) - */ - -import tap from 'tap'; -import fs from 'fs-extra'; -import path from 'path'; -import runSWRegister from '../../src/run-sw-register'; - -/* eslint-disable fecs-camelcase */ -let test = tap.test; - -test('sw-regisrer should generate ok', t => { - let publicDir = path.resolve('./sw-register.test'); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - fs.mkdirSync(publicDir); - - let context = { - public_dir: publicDir, - config: { - root: '/', - service_worker: {} - }, - log: console - }; - - return runSWRegister.call(context).then(() => { - let workerPath = path.join(publicDir, 'sw-register.js'); - let swRegisterFileCon = fs.readFileSync(workerPath, 'utf-8'); - - t.ok(fs.existsSync(workerPath)); - t.ok(swRegisterFileCon.includes('sw.js')); - t.ok(/sw\.js\?v=\d{14}/.test(swRegisterFileCon)); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); - }, error => { - console.error(error); - fs.existsSync(publicDir) && fs.removeSync(publicDir); - t.end(); - }); -}); diff --git a/source/style.css b/source/style.css new file mode 100644 index 0000000..fbd52f7 --- /dev/null +++ b/source/style.css @@ -0,0 +1,272 @@ +html, html>body { + margin: 0px !important; + padding: 0px !important; + height: 100%; + width: 100%; +} +body { + font-family: "Helvetica Neue", Ubuntu, "WenQuanYi Micro Hei", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Micro Hei Mono", "WenQuanYi Zen Hei", "WenQuanYi Zen Hei", "Apple LiGothic Medium", "SimHei", "ST Heiti", "WenQuanYi Zen Hei Sharp", Arial, sans-serif; + -webkit-font-smoothing:antialiased; + line-height: 1.8em; + text-shadow: 0 0 1px rgba(255,255,255,0.1); + background: #fff; +} +img {border-width: 0px;} +a{ + color: #000; + text-decoration: none; + outline:none; + border:none; +} +.list, .list li, .list-left li { + list-style: none; + list-style-type: none; + margin: 0px; + padding: 0px; +} +.pos-f { + position: fixed; +} +.left-100 { + width: 100%; + height: 100%; +} +.blur { + -webkit-filter: blur(3px); + filter: blur(3px); +} +.tr3 { + transition: all .3s; +} +#DonateText { + position: fixed; + font-size: 12px; + width: 70px; + height: 70px; + line-height: 70px; + color: #fff; + background: #ffd886 url(images/like.svg) no-repeat center 10px; + background-size: 20px; + border-radius: 35px; + text-align: center; + left: calc(50% - 120px); + top: calc(50% - 60px); + z-index: -1; + transform: rotatez(-15deg ); +} +#donateBox { + left: calc(50% - 150px); + top: calc(50% - 15px); + background-color: #fff; + border: 1px solid #ddd; + border-radius: 6px; + width: 299px; + height: 28px; + float: left; + z-index: 1; +} +#donateBox li { + width: 74px; + float: left; + text-align: center; + border-left: 1px solid #ddd; + background: no-repeat center center; + background-color: rgba(204, 217, 220,0.1); + background-size: 45px; + transition: all .3s; + cursor: pointer; + overflow: hidden; + line-height: 600px; + height: 28px; + -webkit-filter: grayscale(1); + filter: grayscale(1); + opacity: 0.5; +} +#donateBox li:hover { + background-color: rgba(204, 217, 220,0.3); + -webkit-filter: grayscale(0); + filter: grayscale(0); + opacity: 1; +} +#donateBox>li:first-child { + border-width: 0; +} +#donateBox a { + display: block; +} +#donateBox #PayPal { + background-image: url(images/paypal.svg); +} +#donateBox>#BTC { + background-image: url(images/bitcoin.svg); + line-height: 28px; +} +#donateBox>#BTC:hover { + overflow: visible; +} +#BTC>button { + opacity: 0; + cursor: pointer; +} +#donateBox #AliPay { + background-image: url(images/alipay.svg); +} +#donateBox #WeChat { + background-image: url(images/wechat.svg); +} +#QRBox { + top: 0; + left: 0; + z-index: 1; + background-color: rgba(255,255,255,0.3); + display: none; + perspective: 400px; +} +#MainBox { + cursor: pointer; + position: absolute; + text-align: center; + width: 200px; + height: 200px; + left: calc(50% - 100px); + top: calc(50% - 100px); + background: #fff no-repeat center center; + background-size: 190px; + border-radius: 6px; + box-shadow: 0px 2px 7px rgba(0,0,0,0.3); + opacity: 0; + transition: all 1s ease-in-out; + transform-style: preserve-3d; + transform-origin: center center; + overflow: hidden; +} +#btc-key { + opacity: 0; + width: 2px; + height: 8px; + overflow: hidden; + left: -2px; + top: -8px; +} +#github { + width: 24px; + height: 24px; + left: calc(50% + 135px); + top: calc(50% - 30px); + background: no-repeat center center url(images/github.svg); + background-size: contain; + opacity: 0.3; + transform: rotatez(15deg ); +} +[data-footnote] { + position: relative; + overflow: hidden; +} +[data-footnote]:hover { + overflow: visible; +} +[data-footnote]::before, [data-footnote]::after { + position: absolute; + transition: all .3s; + transform: translate3d(-50%,0,0); + opacity: 0; + left: 37px; + z-index: 10; +} +[data-footnote]::before { + content: attr(data-footnote); + border-radius: 6px; + background-color: rgba(100,100,100,0.8); + color: #fff; + height: 24px; + line-height: 24px; + padding: 0 6px; + font-size: 12px; + white-space: nowrap; + top: -24px; + left: 37px; +} +[data-footnote]::after { + content: ''; + border: 5px solid #333; + border-color: rgba(100,100,100,0.8) transparent transparent transparent; + top: 0; + left: 37px; +} +[data-footnote]:hover::before,[data-footnote]:hover::after { + opacity: 1; +} +[data-footnote]:hover::before,[data-footnote]:hover::after { + transform: translate3d(-50%,-7px,0); +} + +#MainBox.showQR { + opacity: 1; + animation-name:showQR; + animation-duration:3s; + animation-timing-function:ease-in-out; + animation-iteration-count:1; + animation-fill-mode:forwards; + -webkit-animation:showQR 3s ease-in-out 0s 1 normal forwards; +} +@keyframes showQR { + from { + transform: rotateX(90deg); + } + 8% { + opacity: 1; + transform: rotateX(-60deg); + } + 18% { + opacity: 1; + transform: rotateX(40deg); + } + 34% { + opacity: 1; + transform: rotateX(-28deg); + } + 44% { + opacity: 1; + transform: rotateX(18deg); + } + 58% { + opacity: 1; + transform: rotateX(-12deg); + } + 72% { + opacity: 1; + transform: rotateX(9deg); + } + 88% { + opacity: 1; + transform: rotateX(-5deg); + } + 96% { + opacity: 1; + transform: rotateX(2deg); + } + to { + opacity: 1; + } +} +#MainBox.hideQR { + opacity: 1; + animation-name:hideQR; + animation-duration:0.5s; + animation-timing-function:ease-in-out; + animation-iteration-count:1; + animation-fill-mode:forwards; + -webkit-animation:hideQR 0.5s ease-in-out 0s 1 normal forwards; +} +@keyframes hideQR { + from { + } + 20%,50% { + transform: scale(1.08,1.08); + opacity: 1; + } + to { + opacity: 0; + transform: rotateZ(40deg) scale(0.6,0.6); + } +} \ No newline at end of file