@@ -10,10 +10,20 @@ const hexToAscii = (hex) => {
1010 }
1111 return ascii ;
1212} ;
13+ const numToHex = ( num , byteLength ) => {
14+ const hexValue = parseInt ( num ) . toString ( 16 ) . toUpperCase ( ) ;
15+ const targetLength = byteLength * 2 ; // バイト数を文字数に変換
16+ return hexValue . padStart ( targetLength , "0" ) ;
17+ } ;
18+ const hexToNum = ( hex ) => {
19+ return parseInt ( hex , 16 ) . toString ( ) ;
20+ } ;
1321// expose to devtool
1422window . toHex = toHex ;
1523window . strToHexStream = strToHexStream ;
1624window . hexToAscii = hexToAscii ;
25+ window . numToHex = numToHex ;
26+ window . hexToNum = hexToNum ;
1727
1828const copyToClipboard = ( text ) => {
1929 const p = document . createElement ( "p" ) ;
@@ -55,7 +65,7 @@ const App = (props) => {
5565
5666 const [ generatedSspWithTag , setGeneratedSspWithTag ] = React . useState ( "" ) ;
5767
58- const [ aspTags , setAspTags ] = React . useState ( [ { id : 1 , tag : "" , payload : "" , payloadMode : "hex" } ] ) ;
68+ const [ aspTags , setAspTags ] = React . useState ( [ { id : 1 , tag : "" , payload : "" , payloadMode : "hex" , numericLength : 2 } ] ) ;
5969 const [ nextTagId , setNextTagId ] = React . useState ( 2 ) ;
6070
6171 const [ generatedAsp , setGeneratedAsp ] = React . useState ( "" ) ;
@@ -73,7 +83,7 @@ const App = (props) => {
7383 adf1Aid,
7484 ramQuota,
7585 nvramQuota,
76- aspTags : aspTags . map ( ( { tag, payload, payloadMode} ) => ( { tag, payload, payloadMode} ) )
86+ aspTags : aspTags . map ( ( { tag, payload, payloadMode, numericLength } ) => ( { tag, payload, payloadMode, numericLength } ) )
7787 } ;
7888
7989 const blob = new Blob ( [ JSON . stringify ( config , null , 2 ) ] , { type : 'application/json' } ) ;
@@ -112,9 +122,10 @@ const App = (props) => {
112122 id : index + 1 ,
113123 tag : tag . tag || "" ,
114124 payload : tag . payload || "" ,
115- payloadMode : tag . payloadMode || "hex"
125+ payloadMode : tag . payloadMode || "hex" ,
126+ numericLength : tag . numericLength || 2
116127 } ) ) ;
117- setAspTags ( newTags . length > 0 ? newTags : [ { id : 1 , tag : "" , payload : "" , payloadMode : "hex" } ] ) ;
128+ setAspTags ( newTags . length > 0 ? newTags : [ { id : 1 , tag : "" , payload : "" , payloadMode : "hex" , numericLength : 2 } ] ) ;
118129 setNextTagId ( newTags . length + 1 ) ;
119130 }
120131 } catch ( error ) {
@@ -141,12 +152,19 @@ const App = (props) => {
141152 let asp = "" ;
142153
143154 // 各タグを処理
144- aspTags . forEach ( ( { tag, payload, payloadMode} ) => {
155+ aspTags . forEach ( ( { tag, payload, payloadMode, numericLength } ) => {
145156 if ( tag ) {
146157 const tagHex = tag . toUpperCase ( ) ;
147158 if ( payload ) {
148- // asciiモードの場合は変換
149- const payloadHex = payloadMode === 'ascii' ? strToHexStream ( payload ) . toUpperCase ( ) : payload . toUpperCase ( ) ;
159+ // モードに応じて変換
160+ let payloadHex ;
161+ if ( payloadMode === 'ascii' ) {
162+ payloadHex = strToHexStream ( payload ) . toUpperCase ( ) ;
163+ } else if ( payloadMode === 'numeric' ) {
164+ payloadHex = numToHex ( payload , numericLength ) . toUpperCase ( ) ;
165+ } else {
166+ payloadHex = payload . toUpperCase ( ) ;
167+ }
150168 const ll = toHex ( payloadHex . length / 2 ) ;
151169 asp += tagHex + ll + payloadHex ;
152170 } else {
@@ -165,7 +183,7 @@ const App = (props) => {
165183 }
166184
167185 const addTag = ( ) => {
168- setAspTags ( [ ...aspTags , { id : nextTagId , tag : "" , payload : "" , payloadMode : "hex" } ] ) ;
186+ setAspTags ( [ ...aspTags , { id : nextTagId , tag : "" , payload : "" , payloadMode : "hex" , numericLength : 2 } ] ) ;
169187 setNextTagId ( nextTagId + 1 ) ;
170188 }
171189
@@ -456,6 +474,12 @@ const App = (props) => {
456474 setAspTags ( aspTags . map ( t =>
457475 t . id === tagItem . id ? { ...t , payloadMode : 'hex' , payload : hexPayload } : t
458476 ) ) ;
477+ } else if ( tagItem . payloadMode === 'numeric' && tagItem . payload ) {
478+ // numericモードの場合、numToHexで変換
479+ const hexPayload = numToHex ( tagItem . payload , tagItem . numericLength ) ;
480+ setAspTags ( aspTags . map ( t =>
481+ t . id === tagItem . id ? { ...t , payloadMode : 'hex' , payload : hexPayload } : t
482+ ) ) ;
459483 } else {
460484 updateTag ( tagItem . id , 'payloadMode' , 'hex' ) ;
461485 }
@@ -482,13 +506,47 @@ const App = (props) => {
482506 // 変換できない場合はモードだけ変更
483507 updateTag ( tagItem . id , 'payloadMode' , 'ascii' ) ;
484508 }
509+ } else if ( tagItem . payloadMode === 'numeric' ) {
510+ // numeric→asciiは直接変換せず、ペイロードをクリア
511+ setAspTags ( aspTags . map ( t =>
512+ t . id === tagItem . id ? { ...t , payloadMode : 'ascii' , payload : '' } : t
513+ ) ) ;
485514 } else {
486515 updateTag ( tagItem . id , 'payloadMode' , 'ascii' ) ;
487516 }
488517 } ,
489518 className : 'w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600'
490519 } ) ,
491520 React . createElement ( 'span' , { className : 'ml-2 text-sm text-gray-900 dark:text-gray-300' } , 'ascii' )
521+ ) ,
522+ React . createElement ( 'label' , { className : 'flex items-center' } ,
523+ React . createElement ( 'input' , {
524+ type : 'radio' ,
525+ name : `payloadMode-${ tagItem . id } ` ,
526+ value : 'numeric' ,
527+ checked : tagItem . payloadMode === 'numeric' ,
528+ onChange : ( ) => {
529+ // 現在hexモードの場合、numericに変換
530+ if ( tagItem . payloadMode === 'hex' && tagItem . payload ) {
531+ try {
532+ const num = hexToNum ( tagItem . payload ) ;
533+ setAspTags ( aspTags . map ( t =>
534+ t . id === tagItem . id ? { ...t , payloadMode : 'numeric' , payload : num } : t
535+ ) ) ;
536+ } catch ( e ) {
537+ // 変換できない場合はモードだけ変更
538+ updateTag ( tagItem . id , 'payloadMode' , 'numeric' ) ;
539+ }
540+ } else {
541+ // ascii→numericは直接変換せず、ペイロードをクリア
542+ setAspTags ( aspTags . map ( t =>
543+ t . id === tagItem . id ? { ...t , payloadMode : 'numeric' , payload : '' } : t
544+ ) ) ;
545+ }
546+ } ,
547+ className : 'w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600'
548+ } ) ,
549+ React . createElement ( 'span' , { className : 'ml-2 text-sm text-gray-900 dark:text-gray-300' } , 'numeric' )
492550 )
493551 )
494552 ) ,
@@ -502,20 +560,56 @@ const App = (props) => {
502560 if ( / ^ [ 0 - 9 A - F ] * $ / . test ( value ) ) {
503561 updateTag ( tagItem . id , 'payload' , value ) ;
504562 }
563+ } else if ( tagItem . payloadMode === 'numeric' ) {
564+ // numericモードは数字のみ、最大値チェック
565+ const value = e . target . value ;
566+ if ( / ^ [ 0 - 9 ] * $ / . test ( value ) ) {
567+ const numValue = parseInt ( value || '0' , 10 ) ;
568+ const maxValue = Math . pow ( 256 , tagItem . numericLength ) - 1 ;
569+ if ( numValue <= maxValue ) {
570+ updateTag ( tagItem . id , 'payload' , value ) ;
571+ }
572+ }
505573 } else {
506574 // asciiモードは制限なし
507575 updateTag ( tagItem . id , 'payload' , e . target . value ) ;
508576 }
509577 } ,
510- placeholder : tagItem . payloadMode === 'hex' ? '例: 0123456789ABCDEF' : '例: Hello World'
578+ placeholder : tagItem . payloadMode === 'hex' ? '例: 0123456789ABCDEF' : tagItem . payloadMode === 'ascii' ? '例: Hello World' : '例: 8000'
579+ } )
580+ ) ,
581+ tagItem . payloadMode === 'numeric' && React . createElement ( 'div' , { className : 'mt-2' } ,
582+ React . createElement ( 'label' , { className : 'block mb-1 text-xs font-medium text-gray-900 dark:text-white' } ,
583+ '長さ (バイト)'
584+ ) ,
585+ React . createElement ( 'input' , {
586+ type : 'number' ,
587+ className : 'bg-white border border-gray-300 text-gray-900 text-xs rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-20 p-1.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white' ,
588+ value : tagItem . numericLength ,
589+ onChange : ( e ) => {
590+ const value = parseInt ( e . target . value , 10 ) ;
591+ if ( value > 0 && value <= 8 ) { // 最大8バイト
592+ updateTag ( tagItem . id , 'numericLength' , value ) ;
593+ }
594+ } ,
595+ min : 1 ,
596+ max : 8 ,
597+ placeholder : '2'
511598 } )
512599 )
513600 ) ,
514601 tagItem . tag && tagItem . payload && React . createElement ( 'div' , { className : 'mt-2' } ,
515602 React . createElement ( 'span' , {
516603 className : 'bg-blue-100 text-blue-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded dark:bg-blue-900 dark:text-blue-300'
517604 } , `LL (長さ): ${ ( ( ) => {
518- const hexPayload = tagItem . payloadMode === 'ascii' ? strToHexStream ( tagItem . payload ) : tagItem . payload ;
605+ let hexPayload ;
606+ if ( tagItem . payloadMode === 'ascii' ) {
607+ hexPayload = strToHexStream ( tagItem . payload ) ;
608+ } else if ( tagItem . payloadMode === 'numeric' ) {
609+ hexPayload = numToHex ( tagItem . payload || '0' , tagItem . numericLength ) ;
610+ } else {
611+ hexPayload = tagItem . payload ;
612+ }
519613 return toHex ( hexPayload . length / 2 ) ;
520614 } ) ( ) } `)
521615 )
0 commit comments